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 */
__PERF_log1(PERF_Private * priv,unsigned long ulData1)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 */
__PERF_log2(PERF_Private * priv,unsigned long ulData1,unsigned long ulData2)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 */
__PERF_log3(PERF_Private * priv,unsigned long ulData1,unsigned long ulData2,unsigned long ulData3)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
__PERF_log8(PERF_Private * priv,unsigned long ulData1,unsigned long ulData2,unsigned long ulData3,unsigned long ulData4,unsigned long ulData5,unsigned long ulData6,unsigned long ulData7,unsigned long ulData8)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
__PERF_LOG_Location(PERF_OBJHANDLE hObject,const char * szFile,unsigned long ulLine,const char * szFunc)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