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 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 51 void __log_Boundary(PERF_OBJHANDLE hObject, 52 PERF_BOUNDARYTYPE eBoundary) 53 { 54 __PERF_LOG_Boundary(hObject, eBoundary); 55 } 56 57 static 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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