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
PERF_PRINT_done(PERF_Private * perf)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
print_header(FILE * fOut)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
PERF_PRINT_setup(PERF_Private * perf,PERF_MODULETYPE eModule)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__
__print_Location(PERF_Private * perf,char const * szFile,unsigned long ulLine,char const * szFunc)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
clear_print_location(PERF_Private * perf)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
print_print_location(PERF_Private * perf,FILE * fOut,int nValues)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 *
PERF_PRINT_create(PERF_Private * perf,PERF_Config * config,PERF_MODULETYPE eModule)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
__print_Boundary(FILE * fOut,PERF_Private * perf,PERF_BOUNDARYTYPE eBoundary)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
__print_Buffer(FILE * fOut,PERF_Private * perf,unsigned long ulAddress1,unsigned long ulAddress2,unsigned long ulSize,PERF_MODULETYPE eModule)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
__print_Command(FILE * fOut,PERF_Private * perf,unsigned long ulCommand,unsigned long ulArgument,PERF_MODULETYPE eModule)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
__print_Create(FILE * fOut,PERF_Private * perf)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
__print_Done(FILE * fOut,PERF_Private * perf)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
__print_Log(FILE * fOut,PERF_Private * perf,unsigned long ulData1,unsigned long ulData2,unsigned long ulData3)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
__print_SyncAV(FILE * fOut,PERF_Private * perf,float pfTimeAudio,float pfTimeVideo,PERF_SYNCOPTYPE eSyncOperation)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
__print_ThreadCreated(FILE * fOut,PERF_Private * perf,unsigned long ulThreadID,unsigned long ulThreadName)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