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 header should be only included from perf.h */ 22 23 /* this union is used to convert a float to a long representation without 24 breaking strict aliasing rules */ 25 union __PERF_float_long 26 { 27 float f; 28 unsigned long l; 29 }; 30 31 /* combine 2 values in a unsigned long */ 32 #define PERF_mask(field, len) \ 33 ( ((unsigned long) (field)) & ((1 << (len)) - 1) ) 34 35 #define PERF_bits(field, start, len) \ 36 ( (((unsigned long) (field)) >> start) & ((1 << (len)) - 1) ) 37 38 #define PERF_log_combine(flag, field, len) \ 39 ( ((unsigned long) (flag)) | (PERF_mask(field, len) & PERF_LOG_NotMask) ) 40 41 #define PERF_COMBINE2(field1, len1, field2, len2) \ 42 ( ( PERF_mask(field1, len1) << (len2) ) | \ 43 PERF_mask(field2, len2) ) 44 45 #define PERF_LOGCOMBINE2(flag, field1, len1, field2, len2) \ 46 PERF_log_combine(flag, PERF_COMBINE2(field1, len1, field2, len2), \ 47 (len1) + (len2)) 48 49 #define PERF_COMBINE3(field1, len1, field2, len2, field3, len3) \ 50 ((( ( PERF_mask(field1, len1) << (len2) ) | \ 51 PERF_mask(field2, len2) ) << (len3) ) | \ 52 PERF_mask(field3, len3) ) 53 54 #define PERF_LOGCOMBINE3(flag, field1, len1, field2, len2, field3, len3) \ 55 PERF_log_combine(flag, \ 56 PERF_COMBINE3(field1, len1, field2, len2, field3, len3), \ 57 (len1) + (len2) + (len3)) 58 59 /*============================================================================= 60 HARD CODED (default) INTERFACE 61 62 This translates each instrumentation directly into a logging call. It is 63 always defined, so that the logs can be done by the custom interface. 64 =============================================================================*/ 65 66 #define __PERF_LOG_Boundary( \ 67 hObject, \ 68 eBoundary) \ 69 PERF_check((hObject), \ 70 __PERF_log1(get_Private(hObject), \ 71 PERF_log_combine(PERF_LOG_Boundary, eBoundary, 26)) ) /* Macro End */ 72 73 /* we squeeze PERF_LOG flag into 2 or 4 bits */ 74 #define __PERF_LOG_Buffer( \ 75 hObject, \ 76 flSending, \ 77 flMultiple, \ 78 flFrame, \ 79 ulAddress1, \ 80 ulAddress2, \ 81 ulSize, \ 82 eModule1, \ 83 eModule2) \ 84 PERF_check((hObject), \ 85 PERF_IsMultiple(flMultiple) ? \ 86 __PERF_log3(get_Private(hObject), \ 87 PERF_IsXfering(flSending) ? \ 88 (PERF_LOG_Buffer | PERF_LOG_Xfering | /* 2 bits */ \ 89 PERF_COMBINE3((ulSize) >> 3, 30 - 2 * PERF_ModuleBits, \ 90 eModule2, PERF_ModuleBits, \ 91 eModule1, PERF_ModuleBits) ) : \ 92 (PERF_LOG_Buffer | flSending | /* 4 bits */ \ 93 PERF_COMBINE2(ulSize, 28 - PERF_ModuleBits, \ 94 eModule1, PERF_ModuleBits) ), \ 95 ( ((unsigned long) (ulAddress1)) & ~3 ) | \ 96 ( PERF_IsFrame (flFrame) ? PERF_LOG_Frame : 0 ) | \ 97 ( PERF_IsMultiple(flMultiple) ? PERF_LOG_Multiple : 0 ), \ 98 (unsigned long) (ulAddress2) ) : \ 99 __PERF_log2(get_Private(hObject), \ 100 PERF_IsXfering(flSending) ? \ 101 (PERF_LOG_Buffer | PERF_LOG_Xfering | /* 2 bits */ \ 102 PERF_COMBINE3((ulSize) >> 3, 30 - 2 * PERF_ModuleBits, \ 103 eModule2, PERF_ModuleBits, \ 104 eModule1, PERF_ModuleBits) ) : \ 105 (PERF_LOG_Buffer | flSending | /* 4 bits */ \ 106 PERF_COMBINE2(ulSize, 28 - PERF_ModuleBits, \ 107 eModule1, PERF_ModuleBits) ), \ 108 ( ((unsigned long) (ulAddress1)) & ~3 ) | \ 109 ( PERF_IsFrame (flFrame) ? PERF_LOG_Frame : 0 ) | \ 110 ( PERF_IsMultiple(flMultiple) ? PERF_LOG_Multiple : 0 ) )) 111 112 #define __PERF_LOG_Command( \ 113 hObject, \ 114 ulSending, \ 115 ulArgument, \ 116 ulCommand, \ 117 eModule) \ 118 PERF_check((hObject), \ 119 __PERF_log3(get_Private(hObject), \ 120 PERF_log_combine(PERF_LOG_Command | ulSending, eModule, 28), \ 121 ((unsigned long) (ulCommand)), \ 122 ((unsigned long) (ulArgument)) ) ) /* Macro End */ 123 124 #define __PERF_LOG_Log( \ 125 hObject, \ 126 ulData1, \ 127 ulData2, \ 128 ulData3) \ 129 PERF_check((hObject), \ 130 __PERF_log3(get_Private(hObject), \ 131 PERF_log_combine(PERF_LOG_Log, ulData1, 28), \ 132 ((unsigned long) (ulData2)), \ 133 ((unsigned long) (ulData3)) ) ) /* Macro End */ 134 135 #define __PERF_LOG_SyncAV( \ 136 hObject, \ 137 fTimeAudio, \ 138 fTimeVideo, \ 139 eSyncOperation) \ 140 do \ 141 { \ 142 union __PERF_float_long uA,uV; \ 143 uA.f = fTimeAudio; uV.f = fTimeVideo; \ 144 PERF_check((hObject), \ 145 __PERF_log3(get_Private(hObject), \ 146 PERF_log_combine(PERF_LOG_Sync, eSyncOperation, 28), \ 147 uA.l, uV.l)); \ 148 }\ 149 while(0) /* Macro End */ 150 151 #define __PERF_LOG_ThreadCreated( \ 152 hObject, \ 153 ulThreadID, \ 154 ulThreadName) \ 155 PERF_check((hObject), \ 156 __PERF_log2(get_Private(hObject), \ 157 PERF_log_combine(PERF_LOG_Thread, ulThreadID, 26), \ 158 ((unsigned long) (ulThreadName)) ) ) /* Macro End */ 159 160 161 /* ============================================================================ 162 PERF LOG Data Structures 163 ============================================================================ */ 164 165 /* private PERF structure for logging */ 166 typedef struct PERF_LOG_Private 167 { 168 unsigned long uBufferCount; /* number of buffers filled */ 169 unsigned long uBufSize; /* size of buffer */ 170 unsigned long *puBuffer; /* start of current buffer */ 171 unsigned long *puEnd; /* 'end' of current buffer */ 172 unsigned long *puPtr; /* current buffer pointer */ 173 FILE *fOut; /* output file */ 174 char *fOutFile; /* output file name */ 175 } PERF_LOG_Private; 176 177 /* log flags used */ 178 enum PERF_LogStamps 179 { 180 /* 1 arguments */ 181 PERF_LOG_Done = 0x00000000, 182 PERF_LOG_Boundary = 0x08000000, 183 /* 2 arguments */ 184 PERF_LOG_Thread = 0x0C000000, 185 /* 3 arguments */ 186 PERF_LOG_Log = 0x10000000, 187 PERF_LOG_Sync = 0x20000000, 188 #ifdef __PERF_LOG_LOCATION__ 189 /* many arguments */ 190 PERF_LOG_Location = 0x30000000, 191 #endif 192 PERF_LOG_Command = 0x40000000, /* - 0x70000000 */ 193 /* 2 or 3 arguments */ 194 PERF_LOG_Buffer = 0x80000000, /* - 0xF0000000 */ 195 196 /* flags and masks */ 197 PERF_LOG_Mask = 0xF0000000, 198 PERF_LOG_NotMask = ~PERF_LOG_Mask, 199 PERF_LOG_Mask2 = 0xFC000000, 200 PERF_LOG_NotMask2 = ~PERF_LOG_Mask2, 201 PERF_LOG_Frame = 0x00000002, 202 PERF_LOG_Multiple = 0x00000001, 203 204 /* NOTE: we identify xfer buffer from upper 2 bits (11) */ 205 PERF_LOG_Xfering = 0x40000000, 206 /* NOTE: we identify other buffer logs from upper 4 bits (1000 or 1011) */ 207 PERF_LOG_Sending = 0x30000000, 208 }; 209 210 211 #ifdef __PERF_LOG_LOCATION__ 212 213 /* PERF log locations are encoded in 6-bits/char. The last 20 characters of 214 the filename and functionname are saved (20*6*2 bits), along with the last 215 12 bits of the line. 4-bit log stamp makes this 240+12+4=256 bits. */ 216 217 /* __PERF_ENCODE_CHAR converts a character to a 6-bit value: 218 a-z => 0-25 219 A-Z => 26-51 220 1-9 => 52-60 221 0 => 'O' (41) 222 . => 61 223 /,\ => 62 224 else,_ => 63 */ 225 #define __PERF_ENCODE_CHAR(c) \ 226 ( ((c) >= 'a' && (c) <= 'z') ? ((c) - 'a') : \ 227 ((c) >= 'A' && (c) <= 'Z') ? ((c) - 'A' + 26) : \ 228 ((c) >= '1' && (c) <= '9') ? ((c) - '1' + 52) : \ 229 (c) == '.' ? 61 : \ 230 (c) == '0' ? ('O' - 'A' + 26) : \ 231 ((c) == '/' || (c) == '\\') ? 62 : 63 ) 232 233 /* Get the i-th character from the end of a string, or '/' if i is too big */ 234 #define __PERF_GET_INDEXED_CHAR(sz, i) (strlen(sz) <= i ? '/' : sz[strlen(sz) - i - 1]) 235 236 /* Encode i-th character of a string (from the end) */ 237 #define __PERF_ENCODE_INDEXED(sz, i) \ 238 __PERF_ENCODE_CHAR(__PERF_GET_INDEXED_CHAR(sz, i)) 239 240 /* Encode and pack 6 characters into 32 bits. Only the left 2 bits of the 241 6th character will fit */ 242 #define __PERF_PACK6(a1,a2,a3,a4,a5,a6) \ 243 (((unsigned long) (a1)) | \ 244 (((unsigned long) (a2)) << 6) | \ 245 (((unsigned long) (a3)) << 12) | \ 246 (((unsigned long) (a4)) << 18) | \ 247 (((unsigned long) (a5)) << 24) | \ 248 ((((unsigned long) (a6)) & 0x30) << 26)) 249 250 #endif 251 252 /* ============================================================================ 253 PERF LOG External methods 254 ============================================================================ */ 255 256 extern void __PERF_LOG_log_common(PERF_Private *perf, unsigned long *time_loc); 257 258 /* ============================================================================ 259 PERF LOG Inline methods 260 ============================================================================ */ 261 #if defined(__PERF_C__) || defined(INLINE_SUPPORTED) 262 263 /* Effects: logs 1 data */ 264 INLINE void __PERF_log1(PERF_Private *priv, 265 unsigned long ulData1) 266 { 267 /* get log private structures */ 268 PERF_LOG_Private *me = priv->pLog; 269 unsigned long *time_loc = me->puPtr++; 270 271 *me->puPtr++ = ulData1; 272 __PERF_LOG_log_common(priv, time_loc); 273 } 274 275 /* Effects: logs 2 data */ 276 INLINE void __PERF_log2(PERF_Private *priv, 277 unsigned long ulData1, 278 unsigned long ulData2) 279 { 280 /* get log private structures */ 281 PERF_LOG_Private *me = priv->pLog; 282 unsigned long *time_loc = me->puPtr++; 283 284 *me->puPtr++ = ulData1; 285 *me->puPtr++ = ulData2; 286 __PERF_LOG_log_common(priv, time_loc); 287 } 288 289 /* Effects: logs 3 data */ 290 INLINE void __PERF_log3(PERF_Private *priv, 291 unsigned long ulData1, 292 unsigned long ulData2, 293 unsigned long ulData3) 294 { 295 /* get log private structures */ 296 PERF_LOG_Private *me = priv->pLog; 297 unsigned long *time_loc = me->puPtr++; 298 299 *me->puPtr++ = ulData1; 300 *me->puPtr++ = ulData2; 301 *me->puPtr++ = ulData3; 302 __PERF_LOG_log_common(priv, time_loc); 303 } 304 305 #ifdef __PERF_LOG_LOCATION__ 306 307 void __PERF_LOG_flush(PERF_LOG_Private *me); 308 309 /* Effects: logs 3 data */ 310 INLINE void 311 __PERF_log8(PERF_Private *priv, 312 unsigned long ulData1, 313 unsigned long ulData2, 314 unsigned long ulData3, 315 unsigned long ulData4, 316 unsigned long ulData5, 317 unsigned long ulData6, 318 unsigned long ulData7, 319 unsigned long ulData8) 320 { 321 /* get log private structures */ 322 PERF_LOG_Private *me = priv->pLog; 323 324 *me->puPtr++ = ulData8; 325 *me->puPtr++ = (ulData1 & PERF_LOG_NotMask) | PERF_LOG_Location; 326 *me->puPtr++ = ulData2; 327 *me->puPtr++ = ulData3; 328 *me->puPtr++ = ulData4; 329 *me->puPtr++ = ulData5; 330 *me->puPtr++ = ulData6; 331 *me->puPtr++ = ulData7; 332 333 /* flush if we reached end of the buffer */ 334 if (me->puPtr > me->puEnd) __PERF_LOG_flush(me); 335 } 336 337 INLINE void 338 __PERF_LOG_Location(PERF_OBJHANDLE hObject, 339 const char *szFile, 340 unsigned long ulLine, 341 const char *szFunc) 342 { 343 if (hObject) 344 { 345 unsigned long a6 = __PERF_ENCODE_INDEXED(szFile, 5); 346 unsigned long a12 = __PERF_ENCODE_INDEXED(szFile, 11); 347 unsigned long a18 = __PERF_ENCODE_INDEXED(szFile, 17); 348 unsigned long b6 = __PERF_ENCODE_INDEXED(szFunc, 5); 349 unsigned long b12 = __PERF_ENCODE_INDEXED(szFunc, 11); 350 unsigned long b18 = __PERF_ENCODE_INDEXED(szFunc, 17); 351 352 /* get log private structures */ 353 __PERF_log8(get_Private(hObject), 354 (a18 & 0xf) | ((b6 & 0xf) << 4) | ((b12 & 0xf) << 8) | 355 ((b18 & 0xf) << 12) | ((ulLine & 0xfff) << 16), 356 __PERF_PACK6(__PERF_ENCODE_INDEXED(szFile, 0), 357 __PERF_ENCODE_INDEXED(szFile, 1), 358 __PERF_ENCODE_INDEXED(szFile, 2), 359 __PERF_ENCODE_INDEXED(szFile, 3), 360 __PERF_ENCODE_INDEXED(szFile, 4), a6), 361 __PERF_PACK6(__PERF_ENCODE_INDEXED(szFile, 6), 362 __PERF_ENCODE_INDEXED(szFile, 7), 363 __PERF_ENCODE_INDEXED(szFile, 8), 364 __PERF_ENCODE_INDEXED(szFile, 9), 365 __PERF_ENCODE_INDEXED(szFile, 10), a12), 366 __PERF_PACK6(__PERF_ENCODE_INDEXED(szFile, 12), 367 __PERF_ENCODE_INDEXED(szFile, 13), 368 __PERF_ENCODE_INDEXED(szFile, 14), 369 __PERF_ENCODE_INDEXED(szFile, 15), 370 __PERF_ENCODE_INDEXED(szFile, 16), a18), 371 __PERF_PACK6(__PERF_ENCODE_INDEXED(szFunc, 0), 372 __PERF_ENCODE_INDEXED(szFunc, 1), 373 __PERF_ENCODE_INDEXED(szFunc, 2), 374 __PERF_ENCODE_INDEXED(szFunc, 3), 375 __PERF_ENCODE_INDEXED(szFunc, 4), b6), 376 __PERF_PACK6(__PERF_ENCODE_INDEXED(szFunc, 6), 377 __PERF_ENCODE_INDEXED(szFunc, 7), 378 __PERF_ENCODE_INDEXED(szFunc, 8), 379 __PERF_ENCODE_INDEXED(szFunc, 9), 380 __PERF_ENCODE_INDEXED(szFunc, 10), b12), 381 __PERF_PACK6(__PERF_ENCODE_INDEXED(szFunc, 12), 382 __PERF_ENCODE_INDEXED(szFunc, 13), 383 __PERF_ENCODE_INDEXED(szFunc, 14), 384 __PERF_ENCODE_INDEXED(szFunc, 15), 385 __PERF_ENCODE_INDEXED(szFunc, 16), b18), 386 __PERF_ENCODE_INDEXED(szFile, 18) | 387 (__PERF_ENCODE_INDEXED(szFile, 19) << 6) | 388 (__PERF_ENCODE_INDEXED(szFunc, 18) << 12) | 389 (__PERF_ENCODE_INDEXED(szFunc, 19) << 18) | 390 ((a6 & 0xf) << 24) | ((a12 & 0xf) << 28) ); 391 } 392 } 393 394 #endif 395 396 #else 397 398 extern void __PERF_log1(PERF_Private *priv, 399 unsigned long ulData1); 400 extern void __PERF_log2(PERF_Private *priv, 401 unsigned long ulData1, 402 unsigned long ulData2); 403 extern void __PERF_log3(PERF_Private *priv, 404 unsigned long ulData1, 405 unsigned long ulData2, 406 unsigned long ulData3); 407 408 #ifdef __PERF_LOG_LOCATION__ 409 410 extern void __PERF_log8(PERF_Private *priv, 411 unsigned long ulData1, 412 unsigned long ulData2, 413 unsigned long ulData3, 414 unsigned long ulData4, 415 unsigned long ulData5, 416 unsigned long ulData6, 417 unsigned long ulData7, 418 unsigned long ulData8); 419 420 421 #define __PERF_LOG_Location(hObject, szFile, ulLine, szFunc) \ 422 do \ 423 { \ 424 if (hObject) \ 425 { \ 426 unsigned long a6 = __PERF_ENCODE_INDEXED(szFile, 5); \ 427 unsigned long a12 = __PERF_ENCODE_INDEXED(szFile, 11); \ 428 unsigned long a18 = __PERF_ENCODE_INDEXED(szFile, 17); \ 429 unsigned long b6 = __PERF_ENCODE_INDEXED(szFunc, 5); \ 430 unsigned long b12 = __PERF_ENCODE_INDEXED(szFunc, 11); \ 431 unsigned long b18 = __PERF_ENCODE_INDEXED(szFunc, 17); \ 432 \ 433 __PERF_log8(get_Private(hObject), \ 434 (a18 & 0xf) | ((b6 & 0xf) << 4) | \ 435 ((b12 & 0xf) << 8) | ((b18 & 0xf) << 12) | \ 436 ((ulLine & 0xfff) << 16), \ 437 __PERF_PACK6(__PERF_ENCODE_INDEXED(szFile, 0), \ 438 __PERF_ENCODE_INDEXED(szFile, 1), \ 439 __PERF_ENCODE_INDEXED(szFile, 2), \ 440 __PERF_ENCODE_INDEXED(szFile, 3), \ 441 __PERF_ENCODE_INDEXED(szFile, 4), a6), \ 442 __PERF_PACK6(__PERF_ENCODE_INDEXED(szFile, 6), \ 443 __PERF_ENCODE_INDEXED(szFile, 7), \ 444 __PERF_ENCODE_INDEXED(szFile, 8), \ 445 __PERF_ENCODE_INDEXED(szFile, 9), \ 446 __PERF_ENCODE_INDEXED(szFile, 10), a12), \ 447 __PERF_PACK6(__PERF_ENCODE_INDEXED(szFile, 12), \ 448 __PERF_ENCODE_INDEXED(szFile, 13), \ 449 __PERF_ENCODE_INDEXED(szFile, 14), \ 450 __PERF_ENCODE_INDEXED(szFile, 15), \ 451 __PERF_ENCODE_INDEXED(szFile, 16), a18), \ 452 __PERF_PACK6(__PERF_ENCODE_INDEXED(szFunc, 0), \ 453 __PERF_ENCODE_INDEXED(szFunc, 1), \ 454 __PERF_ENCODE_INDEXED(szFunc, 2), \ 455 __PERF_ENCODE_INDEXED(szFunc, 3), \ 456 __PERF_ENCODE_INDEXED(szFunc, 4), b6), \ 457 __PERF_PACK6(__PERF_ENCODE_INDEXED(szFunc, 6), \ 458 __PERF_ENCODE_INDEXED(szFunc, 7), \ 459 __PERF_ENCODE_INDEXED(szFunc, 8), \ 460 __PERF_ENCODE_INDEXED(szFunc, 9), \ 461 __PERF_ENCODE_INDEXED(szFunc, 10), b12), \ 462 __PERF_PACK6(__PERF_ENCODE_INDEXED(szFunc, 12), \ 463 __PERF_ENCODE_INDEXED(szFunc, 13), \ 464 __PERF_ENCODE_INDEXED(szFunc, 14), \ 465 __PERF_ENCODE_INDEXED(szFunc, 15), \ 466 __PERF_ENCODE_INDEXED(szFunc, 16), b18), \ 467 __PERF_ENCODE_INDEXED(szFile, 18) | \ 468 (__PERF_ENCODE_INDEXED(szFile, 19) << 6) | \ 469 (__PERF_ENCODE_INDEXED(szFunc, 18) << 12) | \ 470 (__PERF_ENCODE_INDEXED(szFunc, 19) << 18) | \ 471 ((a6 & 0xf) << 24) | ((a12 & 0xf) << 28)); \ 472 } \ 473 } \ 474 while (0); 475 476 #endif 477 478 #endif 479 480