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 #include "perf.h"
     22 #include "perf_config.h"
     23 
     24 #define PERF_MAX_LOG_LENGTH (sizeof(unsigned long) * 8)
     25 
     26 /* ============================================================================
     27    PERF LOG Methods
     28 ============================================================================ */
     29 
     30 /* Effects: flush log */
     31 void __PERF_LOG_flush(PERF_LOG_Private *me)
     32 {
     33     /* only flush if we collected data */
     34     if (me->puPtr > me->puBuffer)
     35     {
     36 		/* open file if we have not yet opened it */
     37 		if (!me->fOut) me->fOut = fopen(me->fOutFile, "wb");
     38 
     39 		if (me->fOut)
     40 		{
     41 			fwrite(me->puBuffer, me->puPtr - me->puBuffer, sizeof(*me->puPtr),
     42 				   me->fOut);
     43 			me->uBufferCount++;
     44 		}
     45 
     46 		/* reset pointer to start of buffer */
     47 		me->puPtr = me->puBuffer;
     48     }
     49 }
     50 
     51 /** The Done method is called at the end of the UC test or UI
     52 *   application.
     53 *   @param phObject
     54 *       Pointer to a handle to the PERF object, which will be
     55 *       deleted and set to NULL upon completion.
     56 *  */
     57 
     58 void __PERF_LOG_done(PERF_Private *perf)
     59 {
     60     PERF_LOG_Private *me = perf->pLog;
     61 
     62     if (me)
     63     {
     64         /* if we could allocate a buffer, we can log the completion */
     65         if (me->puBuffer && me->fOutFile)
     66         {
     67             __PERF_log1(perf, PERF_LOG_Done);
     68 
     69             __PERF_LOG_flush(me);   /* flush log */
     70         }
     71 
     72         /* free buffer */
     73         if (me->puBuffer) free(me->puBuffer);
     74         me->puBuffer = NULL;
     75 
     76         /* free file name string */
     77         if (me->fOutFile) free(me->fOutFile);
     78         me->fOutFile = NULL;
     79 
     80         /* close file */
     81         if (me->fOut) fclose(me->fOut);
     82         me->fOut = NULL;
     83 
     84         fprintf(stderr,
     85                 "PERF Instrumentation [%c%c%c%c %05ld-%08lx] produced"
     86                 " %ld buffers\n",
     87                 PERF_FOUR_CHARS(perf->ulID), perf->ulPID,
     88                 (unsigned long) perf,
     89                 me->uBufferCount);
     90 
     91         /* delete LOG private structure */
     92         free(me);
     93         perf->pLog = NULL;
     94     }
     95 }
     96 
     97 /* Effects: creates LOG private object and logs initial block of information */
     98 PERF_LOG_Private *__PERF_LOG_create(PERF_Private *perf,
     99                                     PERF_Config *config,
    100                                     PERF_MODULETYPE eModule)
    101 {
    102     PERF_LOG_Private *me =
    103         perf->pLog = (PERF_LOG_Private *) malloc (sizeof (PERF_LOG_Private));
    104 
    105     if (me)
    106     {
    107         me->fOut = NULL;
    108         me->uBufferCount = 0;
    109         me->uBufSize = config->buffer_size;
    110 
    111         /* limit buffer size to allow at least one log creation */
    112         if (me->uBufSize < PERF_MAX_LOG_LENGTH)
    113         {
    114             me->uBufSize = PERF_MAX_LOG_LENGTH;
    115         }
    116 
    117         me->puBuffer =
    118         (unsigned long *) malloc (sizeof (unsigned long) * me->uBufSize);
    119         me->fOutFile = (char *) malloc (strlen(config->trace_file) + 34);
    120         if (me->puBuffer && me->fOutFile)
    121         {
    122             perf->uMode |= PERF_Mode_Log; /* we are logging */
    123 
    124             me->puPtr = me->puBuffer;   /* start at beginning of buffer */
    125             me->puEnd = me->puBuffer + me->uBufSize - PERF_MAX_LOG_LENGTH;
    126 
    127             sprintf(me->fOutFile, "%s-%05lu-%08lx-%c%c%c%c.trace",
    128                     config->trace_file, perf->ulPID, (unsigned long) perf,
    129                     PERF_FOUR_CHARS(perf->ulID));
    130 
    131             /* for delayed open we don't try to open the file until we need to
    132                save a buffer into it */
    133             if (!config->delayed_open)
    134             {
    135                 me->fOut = fopen(me->fOutFile, "ab");
    136             }
    137             else
    138             {
    139                 me->fOut = NULL;
    140             }
    141             /* save initial data to the log */
    142 
    143             *me->puPtr++ = (unsigned long) eModule; /* module ID */
    144             *me->puPtr++ = perf->ulID;  /* ID */
    145             *me->puPtr++ = perf->ulPID; /* process ID */
    146 
    147             /* original tempTime stamp */
    148             *me->puPtr++ = TIME_SECONDS(perf->time);
    149             *me->puPtr++ = TIME_MICROSECONDS(perf->time);
    150         }
    151 
    152 		/* if some allocation or opening failed, delete object */
    153 		if (!me->puBuffer || !me->fOutFile || (!config->delayed_open && !me->fOut))
    154         {
    155 			perf->uMode &= ~PERF_Mode_Log; /* delete logging flag */
    156             __PERF_LOG_done(perf);
    157         }
    158     }
    159 
    160     /* it may have been deleted already, so we read it again */
    161     return(perf->pLog);
    162 }
    163 
    164 /* Effects: appends tempTime stamp to log */
    165 void __PERF_LOG_log_common(PERF_Private *perf, unsigned long *time_loc)
    166 {
    167     unsigned long delta = 0;
    168     PERF_LOG_Private *me = perf->pLog; /* get LOG private object */
    169 
    170     /* get tempTime of from last tempTime stamp */
    171     TIME_GET(perf->tempTime);
    172     delta = TIME_DELTA(perf->tempTime, perf->time);
    173 
    174     *time_loc = delta;   /* save time stamp */
    175 
    176     /* save tempTime stamp as last tempTime stamp */
    177     TIME_COPY(perf->time, perf->tempTime);
    178 
    179     /* flush if we reached end of the buffer */
    180     if (me->puPtr > me->puEnd) __PERF_LOG_flush(me);
    181 }
    182 
    183