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