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 #ifdef __PERF_CUSTOMIZABLE__
     22 
     23     #define __PERF_PRINT_C__
     24 
     25     #include "perf_config.h"
     26     #include "perf.h"
     27     #include "perf_print.h"
     28 
     29 /* ============================================================================
     30    DEBUG PRINT METHODS
     31 ============================================================================ */
     32 
     33 void PERF_PRINT_done(PERF_Private *perf)
     34 {
     35     PERF_PRINT_Private *me = perf->cip.pDebug;
     36 
     37     /* close debug file unless stdout or stderr */
     38     if (me->fDebug && me->fDebug != stdout &&
     39         me->fDebug != stderr) fclose(me->fDebug);
     40 
     41     /* free allocated strings */
     42     free(me->info);    me->info = NULL;
     43 
     44     /* free private structure */
     45     free(me);
     46     perf->cip.pDebug = NULL;
     47 }
     48 
     49 char * const domains_normal[] = { "AD,", "VD,", "ID,", "AE,", "VE,", "IE,"};
     50 char * const domains_csv[]    = { "+AD", "+VD", "+ID", "+AE", "+VE", "+IE"};
     51 
     52 static
     53 void print_header(FILE *fOut)
     54 {
     55     fprintf(fOut, "time,PID,handle,name,domAD,domVD,domID,domAE,domVE,domIE,"
     56             "type,operation\n");
     57 }
     58 
     59 int PERF_PRINT_setup(PERF_Private *perf, PERF_MODULETYPE eModule)
     60 {
     61     PERF_PRINT_Private *me = perf->cip.pDebug;
     62     /* we concatenate the following fields for a unique and informative ID:
     63        PID, address, domain, type */
     64 
     65     /* common variables that differ from CSV and text output */
     66     char const * const * domains, *missing, *separator;
     67 
     68     /* data needed for info field */
     69     unsigned long type = eModule & PERF_ModuleMask;
     70 
     71     /* set up common variables */
     72     if (me->csv)
     73     {
     74         domains = (char const * const *) domains_normal;
     75         missing = separator = ",";
     76         me->prompt = "";
     77         print_header(me->fDebug);
     78     }
     79     else
     80     {
     81         domains = (char const * const *) domains_csv;
     82         missing = "";
     83         separator = ", ";
     84         me->prompt = "<";
     85     }
     86 
     87     me->info = (char *) malloc(3+9+1+8+2+6+4+2+7+12+8+16+2 + 100);
     88     if (me->info)
     89     {
     90 
     91         sprintf(me->info,
     92                 "%s"           /* info separator start */
     93                 "%ld"          /* PID */
     94                 "%s"           /* separator */
     95                 "%08lx"        /* handle */
     96                 "%s"           /* separator */
     97                 "%s"           /* name tag */
     98                 "%c%c%c%c"     /* name (fourcc) */
     99                 "%s"           /* separator */
    100                 "%s"           /* domain tag */
    101                 "%s%s%s%s%s%s" /* domain */
    102                 "%s"           /* module tag */
    103                 "%s"           /* module */
    104                 "%s"           /* info separator end */
    105                 ,
    106                 me->csv ? separator : "> {",
    107                 perf->ulPID,
    108                 me->csv ? separator : "-",
    109                 (unsigned long) perf,
    110                 separator,
    111                 /* name tag */
    112                 me->csv ? "" : "name: ",
    113                 /* name (fourcc) */
    114                 PERF_FOUR_CHARS(perf->ulID),
    115                 separator,
    116                 /* domain tag */
    117                 me->csv ? "" : "domain: ",
    118                 /* domain */
    119                 (eModule & PERF_ModuleAudioDecode) ? domains[0] : missing,
    120                 (eModule & PERF_ModuleVideoDecode) ? domains[1] : missing,
    121                 (eModule & PERF_ModuleImageDecode) ? domains[2] : missing,
    122                 (eModule & PERF_ModuleAudioEncode) ? domains[3] : missing,
    123                 (eModule & PERF_ModuleVideoEncode) ? domains[4] : missing,
    124                 (eModule & PERF_ModuleImageEncode) ? domains[5] : missing,
    125                 /* module tag */
    126                 me->csv ? "" : ", module: ",  /* note: separator added for CSV */
    127                 /* module */
    128                 (type < PERF_ModuleMax) ? PERF_ModuleTypes[type] : "INVALID",
    129                 /* info separator end */
    130                 me->csv ? separator : "} ");
    131     }
    132 
    133     /* we succeed if we could allocate the info string */
    134     return(me->info != NULL);
    135 }
    136 
    137 #ifdef __PERF_LOG_LOCATION__
    138 void __print_Location(PERF_Private *perf,
    139                       char const *szFile,
    140                       unsigned long ulLine,
    141                       char const *szFunc)
    142 {
    143     /* save location for printing */
    144     PERF_PRINT_Private *me = perf->cip.pDebug;
    145 
    146     me->szFile = szFile;
    147     me->szFunc = szFunc;
    148     me->ulLine = ulLine;
    149 }
    150 
    151 void clear_print_location(PERF_Private *perf)
    152 {
    153     PERF_PRINT_Private *me = perf->cip.pDebug;
    154 
    155     /* clear location information */
    156     me->szFile = me->szFunc = NULL;
    157     me->ulLine = 0;
    158 }
    159 
    160 void print_print_location(PERF_Private *perf, FILE *fOut, int nValues)
    161 {
    162     PERF_PRINT_Private *me = perf->cip.pDebug;
    163 
    164     /* print location information if specified */
    165     if (me->szFile && me->szFunc)
    166     {
    167         /* align filenames for CSV format */
    168         if (me->csv)
    169         {
    170             while (nValues < 7)
    171             {
    172                 fprintf(fOut, ",");
    173                 nValues++;
    174             }
    175         }
    176         fprintf(fOut, "%s%s%s%lu%s%s%s\n",
    177                 me->csv ? "," : " in ",
    178                 me->szFile,
    179                 me->csv ? "," : ":line ",
    180                 me->ulLine,
    181                 me->csv ? "," : ":",
    182                 me->szFunc,
    183                 me->csv ? "" : "()");
    184 
    185         /* clear print location */
    186         clear_print_location(perf);
    187     }
    188     else
    189     {   /* if no info is specified, we still need to print the new line */
    190         fprintf(fOut, "\n");
    191     }
    192 }
    193 
    194 #define __LINE_END__ ""
    195 #else
    196 #define __LINE_END__ "\n"
    197 #define print_print_location(perf, fOut, nValues)
    198 #endif
    199 
    200 PERF_PRINT_Private *
    201 PERF_PRINT_create(PERF_Private *perf, PERF_Config *config,
    202                   PERF_MODULETYPE eModule)
    203 {
    204     char *fOutFile = NULL;
    205     FILE *fOut = NULL;
    206     PERF_PRINT_Private *me =
    207     perf->cip.pDebug = malloc(sizeof(PERF_PRINT_Private));
    208 
    209     if (me)
    210     {
    211         me->csv = config->csv;
    212         me->fDebug = me->fPrint = NULL;
    213         me->info = me->prompt = NULL;
    214         perf->uMode |= PERF_Mode_Print;
    215 
    216 #ifdef __PERF_LOG_LOCATION__
    217         /* no location information yet */
    218         clear_print_location(perf);
    219 #endif
    220         /* set up fDebug and fPrint file pointers */
    221         if (config->log_file)
    222         {
    223             /* open log file unless STDOUT or STDERR is specified */
    224             if (!strcasecmp(config->log_file, "STDOUT")) fOut = stdout;
    225             else if (!strcasecmp(config->log_file, "STDERR")) fOut = stderr;
    226             else
    227             {
    228                 /* expand file name with PID and name */
    229                 fOutFile = (char *) malloc (strlen(config->log_file) + 32);
    230                 if (fOutFile)
    231                 {
    232                     sprintf(fOutFile, "%s-%05lu-%08lx-%c%c%c%c.log",
    233                             config->log_file, perf->ulPID, (unsigned long) perf,
    234                             PERF_FOUR_CHARS(perf->ulID));
    235                     fOut = fopen(fOutFile, "at");
    236 
    237                     /* free new file name */
    238                     free(fOutFile);
    239                     fOutFile = NULL;
    240                 }
    241 
    242                 /* if could not open output, set it to STDOUT */
    243                 if (!fOut) fOut = stdout;
    244             }
    245             me->fDebug = me->fPrint = fOut;
    246 
    247         }
    248         else if (config->detailed_debug)
    249         {
    250             /* detailed debug is through stderr */
    251             me->fDebug = me->fPrint = stderr;
    252         }
    253         else if (config->debug)
    254         {
    255             /* normal debug is through stdout (buffers are not printed) */
    256             me->fDebug = stdout;
    257             me->fPrint = NULL;
    258         }
    259 
    260         PERF_PRINT_setup(perf, eModule);
    261 
    262         if (me->fDebug) __print_Create(me->fDebug, perf);
    263     }
    264 
    265     return(me);
    266 }
    267 
    268 void __print_Boundary(FILE *fOut,
    269                       PERF_Private *perf, PERF_BOUNDARYTYPE eBoundary)
    270 {
    271     /* get debug private structure */
    272     PERF_PRINT_Private *me = perf->cip.pDebug;
    273 
    274     unsigned long boundary = ((unsigned long) eBoundary) & PERF_BoundaryMask;
    275 
    276     fprintf(fOut, "%s%ld.%06ld%sBoundary%s0x%x%s%s%s%s" __LINE_END__,
    277             me->prompt, TIME_SECONDS(perf->time), TIME_MICROSECONDS(perf->time),
    278             me->info,
    279             me->csv ? "," : "(",
    280             eBoundary,
    281             me->csv ? "," : " = ",
    282             PERF_IsStarted(eBoundary) ? "started " : "completed ",
    283             (boundary < PERF_BoundaryMax  ?
    284              PERF_BoundaryTypes[boundary] : "INVALID"),
    285             me->csv ? "" : ")");
    286 
    287     print_print_location(perf, fOut, 2);
    288 }
    289 
    290 static const char *sendRecvTxt[] = {
    291         "received", "sending", "requesting", "sent",
    292     };
    293 
    294 void __print_Buffer(FILE *fOut,
    295                     PERF_Private *perf,
    296                     unsigned long ulAddress1,
    297                     unsigned long ulAddress2,
    298                     unsigned long ulSize,
    299                     PERF_MODULETYPE eModule)
    300 {
    301 
    302     /* get debug private structure */
    303     PERF_PRINT_Private *me = perf->cip.pDebug;
    304 
    305     unsigned long module1 = ((unsigned long) eModule) & PERF_ModuleMask;
    306     unsigned long module2 = (((unsigned long) eModule) >> PERF_ModuleBits) & PERF_ModuleMask;
    307     int xfering  = PERF_IsXfering ((unsigned long) eModule);
    308     int sendIx   = (PERF_GetSendRecv ((unsigned long) eModule) >> 28) & 3;
    309     int sending  = PERF_IsSending ((unsigned long) eModule);
    310     int frame    = PERF_IsFrame   ((unsigned long) eModule);
    311     int multiple = PERF_IsMultiple((unsigned long) eModule);
    312 
    313     if (!xfering && sending) module2 = module1;
    314 
    315     fprintf(fOut, "%s%ld.%06ld%sBuffer%s%s%s%s%s%s%s%s%s0x%lx%s0x%lx",
    316             me->prompt, TIME_SECONDS(perf->time), TIME_MICROSECONDS(perf->time),
    317             me->info,
    318             me->csv ? "," : "(",
    319             xfering ? "xfering" : sendRecvTxt[sendIx],
    320             me->csv ? "," : " ",
    321             frame ? "frame" : "buffer",
    322             me->csv ? "," : (xfering || !sending) ? " from=" : "",
    323             (xfering || !sending) ?
    324             (module1 < PERF_ModuleMax ? PERF_ModuleTypes[module1] : "INVALID") :
    325             "",
    326             me->csv ? "," : (xfering || sending) ? " to=" : "",
    327             (xfering || sending) ?
    328             (module2 < PERF_ModuleMax ? PERF_ModuleTypes[module2] : "INVALID") :
    329             "",
    330             me->csv ? "," : " size=",
    331             ulSize,
    332             me->csv ? "," : " addr=",
    333             ulAddress1);
    334 
    335     /* print second address if supplied */
    336     if (multiple)
    337     {
    338         fprintf(fOut, "%s0x%lx",
    339                 me->csv ? "," : " addr=",
    340                 ulAddress2);
    341     }
    342 
    343     fprintf(fOut, "%s" __LINE_END__,
    344             me->csv ? "" : ")");
    345 
    346     print_print_location(perf, fOut, 6 + (multiple ? 1 : 0));
    347 }
    348 
    349 void __print_Command(FILE *fOut,
    350                      PERF_Private *perf,
    351                      unsigned long ulCommand,
    352 					 unsigned long ulArgument,
    353                      PERF_MODULETYPE eModule)
    354 {
    355     /* get debug private structure */
    356     PERF_PRINT_Private *me = perf->cip.pDebug;
    357 
    358     unsigned long module = ((unsigned long) eModule) & PERF_ModuleMask;
    359     int sendIx   = (PERF_GetSendRecv ((unsigned long) eModule) >> 28) & 3;
    360     int sending  = PERF_IsSending(((unsigned long) eModule) & ~PERF_ModuleMask);
    361 
    362     fprintf(fOut, "%s%ld.%06ld%sCommand%s%s%s%s%s0x%lx%s0x%lx%s%s%s" __LINE_END__,
    363             me->prompt, TIME_SECONDS(perf->time), TIME_MICROSECONDS(perf->time),
    364             me->info,
    365             me->csv ? "," : "(",
    366             sendRecvTxt[sendIx],
    367             me->csv ? "," : sending ? " to=" : " from=",
    368             module < PERF_ModuleMax ? PERF_ModuleTypes[module] : "INVALID",
    369             me->csv ? "," : " cmd=",
    370             ulCommand,
    371 			me->csv ? "," : "(",
    372 			ulArgument,
    373             me->csv ? "," : ") = ",
    374             (ulCommand != PERF_CommandStatus  ?
    375              "INVALID" : PERF_CommandTypes[ulCommand]),
    376             me->csv ? "" : ")");
    377 
    378     print_print_location(perf, fOut, 5);
    379 }
    380 
    381 void __print_Create(FILE *fOut,
    382                     PERF_Private *perf)
    383 {
    384     /* get debug private structure */
    385     PERF_PRINT_Private *me = perf->cip.pDebug;
    386 
    387     fprintf(fOut, "%s%ld.%06ld%sCreate" __LINE_END__,
    388             me->prompt, TIME_SECONDS(perf->time), TIME_MICROSECONDS(perf->time),
    389             me->info);
    390 
    391     print_print_location(perf, fOut, 0);
    392 }
    393 
    394 void __print_Done(FILE *fOut,
    395                   PERF_Private *perf)
    396 {
    397     /* get debug private structure */
    398     PERF_PRINT_Private *me = perf->cip.pDebug;
    399 
    400     fprintf(fOut, "%s%ld.%06ld%sDone" __LINE_END__,
    401             me->prompt, TIME_SECONDS(perf->time), TIME_MICROSECONDS(perf->time),
    402             me->info);
    403 
    404     print_print_location(perf, fOut, 0);
    405 }
    406 
    407 void __print_Log(FILE *fOut,
    408                  PERF_Private *perf,
    409                  unsigned long ulData1, unsigned long ulData2,
    410                  unsigned long ulData3)
    411 {
    412     /* get debug private structure */
    413     PERF_PRINT_Private *me = perf->cip.pDebug;
    414 
    415     fprintf(fOut, "%s%ld.%06ld%sLog%s0x%lx%s0x%lx%s0x%lx%s" __LINE_END__,
    416             me->prompt, TIME_SECONDS(perf->time), TIME_MICROSECONDS(perf->time),
    417             me->info,
    418             me->csv ? "," : "(",
    419             ulData1,
    420             me->csv ? "," : ", ",
    421             ulData2,
    422             me->csv ? "," : ", ",
    423             ulData3,
    424             me->csv ? "" : ")");
    425 
    426     print_print_location(perf, fOut, 3);
    427 }
    428 
    429 void __print_SyncAV(FILE *fOut,
    430                     PERF_Private *perf,
    431                     float pfTimeAudio,
    432                     float pfTimeVideo,
    433                     PERF_SYNCOPTYPE eSyncOperation)
    434 {
    435     /* get debug private structure */
    436     PERF_PRINT_Private *me = perf->cip.pDebug;
    437 
    438     unsigned long op = (unsigned long) eSyncOperation;
    439 
    440     fprintf(fOut, "%s%ld.%06ld%sSyncAV%s%g%s%g%s%s%s" __LINE_END__,
    441             me->prompt, TIME_SECONDS(perf->time), TIME_MICROSECONDS(perf->time),
    442             me->info,
    443             me->csv ? "," : "(audioTS=",
    444             pfTimeAudio,
    445             me->csv ? "," : " videoTS=",
    446             pfTimeVideo,
    447             me->csv ? "," : " op=",
    448             (op < PERF_SyncOpMax ? PERF_SyncOpTypes[op] : "INVALID"),
    449             me->csv ? "" : ")");
    450 
    451     print_print_location(perf, fOut, 3);
    452 }
    453 
    454 void __print_ThreadCreated(FILE *fOut,
    455                            PERF_Private *perf,
    456                            unsigned long ulThreadID,
    457                            unsigned long ulThreadName)
    458 {
    459     /* get debug private structure */
    460     PERF_PRINT_Private *me = perf->cip.pDebug;
    461 
    462     fprintf(fOut, "%s%ld.%06ld%sThread%s%ld%s%c%c%c%c%s" __LINE_END__,
    463             me->prompt, TIME_SECONDS(perf->time), TIME_MICROSECONDS(perf->time),
    464             me->info,
    465             me->csv ? "," : "(pid=",
    466             ulThreadID,
    467             me->csv ? "," : " name=",
    468             PERF_FOUR_CHARS(ulThreadName),
    469             me->csv ? "" : ")");
    470 
    471     print_print_location(perf, fOut, 2);
    472 }
    473 
    474 #endif
    475