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 /* NOTE: This source file should be only included from perf.c */
22 
23 /*=============================================================================
24     CUSTOMIZABLE INTERFACES
25 =============================================================================*/
26 
27 #include "perf_config.h"
28 #include "perf_print.h"
29 #include "perf_rt.h"
30 
31 void __PERF_CUSTOM_setup_for_log_only(PERF_OBJHANDLE hObject);
32 void __PERF_CUSTOM_setup_common(PERF_OBJHANDLE hObject);
33 
34 /*=============================================================================
35     time stamp methods
36 =============================================================================*/
37 
38 INLINEORSTATIC
get_time(PERF_Private * me)39 void get_time(PERF_Private *me)
40 {
41     /* get replay tempTime if replaying */
42     if (me->uMode & PERF_Mode_Replay) return;
43 
44     /* otherwise, get time of the day */
45     TIME_GET(me->time);
46 }
47 
48 /** Customizable PERF interfaces for logging only.  These
49  *  correspond -- and are wrappers -- to the __PERF macros */
50 static
__log_Boundary(PERF_OBJHANDLE hObject,PERF_BOUNDARYTYPE eBoundary)51 void __log_Boundary(PERF_OBJHANDLE hObject,
52                     PERF_BOUNDARYTYPE eBoundary)
53 {
54     __PERF_LOG_Boundary(hObject, eBoundary);
55 }
56 
57 static
__log_Buffer(PERF_OBJHANDLE hObject,unsigned long ulAddress1,unsigned long ulAddress2,unsigned long ulSize,unsigned long ulModuleAndFlags)58 void __log_Buffer(PERF_OBJHANDLE hObject,
59                   unsigned long ulAddress1,
60                   unsigned long ulAddress2,
61                   unsigned long ulSize,
62                   unsigned long ulModuleAndFlags)
63 {
64     __PERF_LOG_Buffer(hObject,
65                       PERF_GetXferSendRecv(ulModuleAndFlags),
66                       ulModuleAndFlags & PERF_FlagMultiple,
67                       ulModuleAndFlags & PERF_FlagFrame,
68                       ulAddress1,
69                       ulAddress2,
70                       ulSize,
71                       ulModuleAndFlags & PERF_ModuleMask,
72 					  (ulModuleAndFlags >> PERF_ModuleBits) & PERF_ModuleMask);
73 }
74 
75 static
__log_Command(PERF_OBJHANDLE hObject,unsigned long ulCommand,unsigned long ulArgument,unsigned long ulModuleAndFlags)76 void __log_Command(PERF_OBJHANDLE hObject,
77                    unsigned long ulCommand,
78 				   unsigned long ulArgument,
79                    unsigned long ulModuleAndFlags)
80 {
81     __PERF_LOG_Command(hObject,
82                        PERF_GetSendRecv(ulModuleAndFlags),
83                        ulCommand,
84 					   ulArgument,
85                        ulModuleAndFlags & PERF_ModuleMask);
86 }
87 
88 static
__log_Log(PERF_OBJHANDLE hObject,unsigned long ulData1,unsigned long ulData2,unsigned long ulData3)89 void __log_Log(PERF_OBJHANDLE hObject,
90                unsigned long ulData1,
91                unsigned long ulData2,
92                unsigned long ulData3)
93 {
94     __PERF_LOG_Log(hObject, ulData1, ulData2, ulData3);
95 }
96 
97 static
__log_SyncAV(PERF_OBJHANDLE hObject,float fTimeAudio,float fTimeVideo,PERF_SYNCOPTYPE eSyncOperation)98 void __log_SyncAV(PERF_OBJHANDLE hObject,
99                   float fTimeAudio,
100                   float fTimeVideo,
101                   PERF_SYNCOPTYPE eSyncOperation)
102 {
103     __PERF_LOG_SyncAV(hObject, fTimeAudio, fTimeVideo, eSyncOperation);
104 }
105 
106 static
__log_ThreadCreated(PERF_OBJHANDLE hObject,unsigned long ulThreadID,unsigned long ulThreadName)107 void __log_ThreadCreated(PERF_OBJHANDLE hObject,
108                          unsigned long ulThreadID,
109                          unsigned long ulThreadName)
110 {
111     __PERF_LOG_ThreadCreated(hObject, ulThreadID, ulThreadName);
112 }
113 
114 /** Customizable PERF interfaces for all operations other than
115  *  logging only. These correspond to the __PERF macros */
116 
117 static
__common_Boundary(PERF_OBJHANDLE hObject,PERF_BOUNDARYTYPE eBoundary)118 void __common_Boundary(PERF_OBJHANDLE hObject,
119                        PERF_BOUNDARYTYPE eBoundary)
120 {
121     PERF_Private *me  = get_Private(hObject);
122 
123     if (me->pLog)
124     {   /* perform log specific operations */
125         __log_Boundary(hObject, eBoundary);
126     }
127     else
128     {   /* we need to get the time stamp to print */
129         get_time(me);
130     }
131 
132     if (me->cip.pDebug)
133     {
134         __print_Boundary(me->cip.pDebug->fDebug,
135                          me, eBoundary);
136     }
137 
138     if (me->cip.pRT)
139     {
140         __rt_Boundary(me, eBoundary);
141     }
142 }
143 
144 static
__common_Buffer(PERF_OBJHANDLE hObject,unsigned long ulAddress1,unsigned long ulAddress2,unsigned long ulSize,unsigned long ulModuleAndFlags)145 void __common_Buffer(PERF_OBJHANDLE hObject,
146                      unsigned long ulAddress1,
147                      unsigned long ulAddress2,
148                      unsigned long ulSize,
149                      unsigned long ulModuleAndFlags)
150 {
151     PERF_Private *me  = get_Private(hObject);
152 
153     if (me->pLog)
154     {   /* perform log specific operations */
155         __log_Buffer(hObject, ulAddress1, ulAddress2, ulSize, ulModuleAndFlags);
156     }
157     else
158     {   /* we need to get the time stamp to print */
159         get_time(me);
160     }
161 
162     if (me->cip.pDebug && me->cip.pDebug->fPrint)
163     {
164         __print_Buffer(me->cip.pDebug->fPrint,
165                        me, ulAddress1, ulAddress2, ulSize, ulModuleAndFlags);
166     }
167 
168     if (me->cip.pRT)
169     {
170         __rt_Buffer(me, ulAddress1, ulAddress2, ulSize, ulModuleAndFlags);
171     }
172 }
173 
174 static
__common_Command(PERF_OBJHANDLE hObject,unsigned long ulCommand,unsigned long ulArgument,unsigned long ulModuleAndFlags)175 void __common_Command(PERF_OBJHANDLE hObject,
176                       unsigned long ulCommand,
177 					  unsigned long ulArgument,
178                       unsigned long ulModuleAndFlags)
179 {
180     PERF_Private *me  = get_Private(hObject);
181 
182     if (me->pLog)
183     {   /* perform log specific operations */
184         __log_Command(hObject, ulCommand, ulArgument, ulModuleAndFlags);
185     }
186     else
187     {   /* we need to get the time stamp to print */
188         get_time(me);
189     }
190 
191     if (me->cip.pDebug && me->cip.pDebug->fDebug)
192     {
193         __print_Command(me->cip.pDebug->fDebug,
194                         me, ulCommand, ulArgument, ulModuleAndFlags);
195     }
196 
197     if (me->cip.pRT)
198     {
199         __rt_Command(me, ulCommand, ulArgument, ulModuleAndFlags);
200     }
201 }
202 
203 static
__common_Log(PERF_OBJHANDLE hObject,unsigned long ulData1,unsigned long ulData2,unsigned long ulData3)204 void __common_Log(PERF_OBJHANDLE hObject,
205                   unsigned long ulData1,
206                   unsigned long ulData2,
207                   unsigned long ulData3)
208 {
209     PERF_Private *me  = get_Private(hObject);
210 
211     if (me->pLog)
212     {   /* perform log specific operations */
213         __log_Log(hObject, ulData1, ulData2, ulData3);
214     }
215     else
216     {   /* we need to get the time stamp to print */
217         get_time(me);
218     }
219 
220     if (me->cip.pDebug && me->cip.pDebug->fDebug)
221     {
222         __print_Log(me->cip.pDebug->fDebug,
223                     me, ulData1, ulData2, ulData3);
224     }
225 
226     if (me->cip.pRT)
227     {
228         __rt_Log(me, ulData1, ulData2, ulData3);
229     }
230 }
231 
232 static
__common_SyncAV(PERF_OBJHANDLE hObject,float pfTimeAudio,float pfTimeVideo,PERF_SYNCOPTYPE eSyncOperation)233 void __common_SyncAV(PERF_OBJHANDLE hObject,
234                      float pfTimeAudio,
235                      float pfTimeVideo,
236                      PERF_SYNCOPTYPE eSyncOperation)
237 {
238     PERF_Private *me  = get_Private(hObject);
239 
240     if (me->pLog)
241     {   /* perform log specific operations */
242         __log_SyncAV(hObject, pfTimeAudio, pfTimeVideo, eSyncOperation);
243     }
244     else
245     {   /* we need to get the time stamp to print */
246         get_time(me);
247     }
248 
249     if (me->cip.pDebug && me->cip.pDebug->fDebug)
250     {
251         __print_SyncAV(me->cip.pDebug->fDebug,
252                        me, pfTimeAudio, pfTimeVideo, eSyncOperation);
253     }
254 
255     if (me->cip.pRT)
256     {
257         __rt_SyncAV(me, pfTimeAudio, pfTimeVideo, eSyncOperation);
258     }
259 }
260 
261 static
__common_ThreadCreated(PERF_OBJHANDLE hObject,unsigned long ulThreadID,unsigned long ulThreadName)262 void __common_ThreadCreated(PERF_OBJHANDLE hObject,
263                             unsigned long ulThreadID,
264                             unsigned long ulThreadName)
265 {
266     PERF_Private *me  = get_Private(hObject);
267 
268     if (me->pLog)
269     {   /* perform log specific operations */
270         __log_ThreadCreated(hObject, ulThreadID, ulThreadName);
271     }
272     else
273     {   /* we need to get the time stamp to print */
274         get_time(me);
275     }
276 
277     if (me->cip.pDebug && me->cip.pDebug->fDebug)
278     {
279         __print_ThreadCreated(me->cip.pDebug->fDebug,
280                               me, ulThreadID, ulThreadName);
281     }
282 
283     if (me->cip.pRT)
284     {
285         __rt_ThreadCreated(me, ulThreadID, ulThreadName);
286     }
287 }
288 
289 #ifdef __PERF_LOG_LOCATION__
290 static
__log_Location(PERF_OBJHANDLE hObject,char const * szFile,unsigned long ulLine,char const * szFunc)291 void __log_Location(PERF_OBJHANDLE hObject,
292                    char const *szFile,
293 				   unsigned long ulLine,
294                    char const *szFunc)
295 {
296     __PERF_LOG_Location(hObject,
297                         szFile,
298                         ulLine,
299                         szFunc);
300 }
301 
302 static
__common_Location(PERF_OBJHANDLE hObject,char const * szFile,unsigned long ulLine,char const * szFunc)303 void __common_Location(PERF_OBJHANDLE hObject,
304                             char const *szFile,
305 				   unsigned long ulLine,
306                    char const *szFunc)
307 {
308     PERF_Private *me  = get_Private(hObject);
309 
310     if (me->pLog)
311     {   /* perform log specific operations */
312         __log_Location(hObject, szFile, ulLine, szFunc);
313     }
314 
315     if (me->cip.pDebug && me->cip.pDebug->fDebug)
316     {
317         __print_Location(me, szFile, ulLine, szFunc);
318     }
319 }
320 #endif
321 
322 
323 void
__PERF_CUSTOM_setup_common(PERF_OBJHANDLE hObject)324 __PERF_CUSTOM_setup_common(PERF_OBJHANDLE hObject)
325 {
326     hObject->ci.Boundary      = __common_Boundary;
327     hObject->ci.Buffer        = __common_Buffer;
328     hObject->ci.Command       = __common_Command;
329     hObject->ci.Log           = __common_Log;
330     hObject->ci.SyncAV        = __common_SyncAV;
331     hObject->ci.ThreadCreated = __common_ThreadCreated;
332 #ifdef __PERF_LOG_LOCATION__
333     hObject->ci.Location      = __common_Location;
334 #endif
335 }
336 
337 void
__PERF_CUSTOM_setup_for_log_only(PERF_OBJHANDLE hObject)338 __PERF_CUSTOM_setup_for_log_only(PERF_OBJHANDLE hObject)
339 {
340     hObject->ci.Boundary      = __log_Boundary;
341     hObject->ci.Buffer        = __log_Buffer;
342     hObject->ci.Command       = __log_Command;
343     hObject->ci.Log           = __log_Log;
344     hObject->ci.SyncAV        = __log_SyncAV;
345     hObject->ci.ThreadCreated = __log_ThreadCreated;
346 #ifdef __PERF_LOG_LOCATION__
347     hObject->ci.Location      = __log_Location;
348 #endif
349 }
350 
351 void
__PERF_CUSTOM_create(PERF_OBJHANDLE hObject,PERF_Config * config,PERF_MODULETYPE eModule)352 __PERF_CUSTOM_create(PERF_OBJHANDLE hObject, PERF_Config *config,
353                      PERF_MODULETYPE eModule)
354 {
355     PERF_Private *me = get_Private(hObject);
356 
357     /* initialize custom fields of the PERF_Private */
358     me->cip.pDebug = NULL;
359     me->cip.pRT = NULL;
360 
361     /* add replay flag and set log file to the replay file so that replayed
362        prints are saved into the log (replay) file */
363     if (config->replay_file)
364     {
365         me->uMode |= PERF_Mode_Replay;
366 
367         if (config->log_file) free(config->log_file);
368         config->log_file    = config->replay_file;
369         config->replay_file = NULL;
370 
371         /** we need to get time stamps set up before we continue
372             at the 2nd call, replay_file is already NULL so we will
373             proceed */
374         return;
375     }
376 
377     /* handle correct output (debug and debug log) */
378     if (config->log_file || config->debug || config->detailed_debug)
379     {
380         /* check if we could create the print structure */
381         if (!PERF_PRINT_create(me, config, eModule))
382         {
383             /* if not, delete replay flag */
384             me->uMode &= ~PERF_Mode_Replay;
385         }
386     }
387 
388     /* handle correct output (debug and debug log) */
389     if (config->realtime)
390     {
391         /* check if we could create the print structure */
392         PERF_RT_create(me, config, eModule);
393     }
394 
395     /* THIS has to be done at the end:
396        if we are only logging, we set up the function table to the log shortcut
397        interface for speed.  Otherwise, we set them to the common interface */
398     if (me->uMode == PERF_Mode_Log)
399     {
400         __PERF_CUSTOM_setup_for_log_only(hObject);
401     }
402     else
403     {
404         __PERF_CUSTOM_setup_common(hObject);
405     }
406 }
407 
__PERF_CUSTOM_done(PERF_Private * me)408 void __PERF_CUSTOM_done(PERF_Private *me)
409 {
410     if (me->uMode & PERF_Mode_Log)
411     {   /* close log */
412         __PERF_LOG_done(me);
413     }
414     else
415     {
416         get_time(me);
417     }
418 
419     /* Complete any debug structures */
420     if (me->cip.pDebug)
421     {
422 		if (me->cip.pDebug->fDebug) __print_Done(me->cip.pDebug->fDebug, me);
423         PERF_PRINT_done(me);
424     }
425 
426     if (me->cip.pRT)
427     {
428         __rt_Done(me);
429         PERF_RT_done(me);
430     }
431 }
432 
433