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 */
__PERF_LOG_flush(PERF_LOG_Private * me)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
__PERF_LOG_done(PERF_Private * perf)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 */
__PERF_LOG_create(PERF_Private * perf,PERF_Config * config,PERF_MODULETYPE eModule)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 */
__PERF_LOG_log_common(PERF_Private * perf,unsigned long * time_loc)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