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
31void __PERF_CUSTOM_setup_for_log_only(PERF_OBJHANDLE hObject);
32void __PERF_CUSTOM_setup_common(PERF_OBJHANDLE hObject);
33
34/*=============================================================================
35    time stamp methods
36=============================================================================*/
37
38INLINEORSTATIC
39void 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 */
50static
51void __log_Boundary(PERF_OBJHANDLE hObject,
52                    PERF_BOUNDARYTYPE eBoundary)
53{
54    __PERF_LOG_Boundary(hObject, eBoundary);
55}
56
57static
58void __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
75static
76void __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
88static
89void __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
97static
98void __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
106static
107void __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
117static
118void __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
144static
145void __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
174static
175void __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
203static
204void __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
232static
233void __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
261static
262void __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__
290static
291void __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
302static
303void __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
323void
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
337void
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
351void
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
408void __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