[DAPL2] sync with WinOF 2.1 branch
[mirror/winof/.git] / inc / complib / cl_perf.h
1 /*\r
2  * Copyright (c) 2005 SilverStorm Technologies.  All rights reserved.\r
3  * Copyright (c) 1996-2003 Intel Corporation. All rights reserved. \r
4  *\r
5  * This software is available to you under the OpenIB.org BSD license\r
6  * below:\r
7  *\r
8  *     Redistribution and use in source and binary forms, with or\r
9  *     without modification, are permitted provided that the following\r
10  *     conditions are met:\r
11  *\r
12  *      - Redistributions of source code must retain the above\r
13  *        copyright notice, this list of conditions and the following\r
14  *        disclaimer.\r
15  *\r
16  *      - Redistributions in binary form must reproduce the above\r
17  *        copyright notice, this list of conditions and the following\r
18  *        disclaimer in the documentation and/or other materials\r
19  *        provided with the distribution.\r
20  *\r
21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
22  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
23  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
24  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
25  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
26  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
27  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
28  * SOFTWARE.\r
29  *\r
30  * $Id$\r
31  */\r
32 \r
33 \r
34 /*\r
35  * Abstract:\r
36  *      Declaration of performance tracking.\r
37  *\r
38  * Environment:\r
39  *      All\r
40  */\r
41 \r
42 \r
43 #ifndef _CL_PERF_H_\r
44 #define _CL_PERF_H_\r
45 \r
46 \r
47 #include <complib/cl_types.h>\r
48 #include <complib/cl_spinlock.h>\r
49 #include <complib/cl_timer.h>\r
50 \r
51 \r
52 /****h* Component Library/Performance Counters\r
53 * NAME\r
54 *       Performance Counters\r
55 *\r
56 * DESCRIPTION\r
57 *       The performance counters allows timing operations to benchmark\r
58 *       software performance and help identify potential bottlenecks.\r
59 *\r
60 *       All performance counters are NULL macros when disabled, preventing them\r
61 *       from adversly affecting performance in builds where the counters are not\r
62 *       used.\r
63 *\r
64 *       Each counter records elapsed time in micro-seconds, minimum time elapsed,\r
65 *       and total number of samples.\r
66 *\r
67 *       Each counter is independently protected by a spinlock, allowing use of\r
68 *       the counters in multi-processor environments.\r
69 *\r
70 *       The impact of serializing access to performance counters is measured,\r
71 *       allowing measurements to be corrected as necessary.\r
72 *\r
73 * NOTES\r
74 *       Performance counters do impact performance, and should only be enabled\r
75 *       when gathering data.  Counters can be enabled or disabled on a per-user\r
76 *       basis at compile time.  To enable the counters, users should define\r
77 *       the PERF_TRACK_ON keyword before including the cl_perf.h file.\r
78 *       Undefining the PERF_TRACK_ON keyword disables the performance counters.\r
79 *       When disabled, all performance tracking calls resolve to no-ops.\r
80 *\r
81 *       When using performance counters, it is the user's responsibility to\r
82 *       maintain the counter indexes.  It is recomended that users define an\r
83 *       enumerated type to use for counter indexes.  It improves readability\r
84 *       and simplifies maintenance by reducing the work necessary in managing\r
85 *       the counter indexes.\r
86 *\r
87 * SEE ALSO\r
88 *       Structures:\r
89 *               cl_perf_t\r
90 *\r
91 *       Initialization:\r
92 *               cl_perf_construct, cl_perf_init, cl_perf_destroy\r
93 *\r
94 *       Manipulation\r
95 *               cl_perf_reset, cl_perf_display, cl_perf_start, cl_perf_update,\r
96 *               cl_perf_log, cl_perf_stop\r
97 *\r
98 *       Macros:\r
99 *               PERF_DECLARE, PERF_DECLARE_START\r
100 *********/\r
101 \r
102 \r
103 /*\r
104  * Number of times the counter calibration test is executed.  This is used\r
105  * to determine the average time to use a performance counter.\r
106  */\r
107 #define PERF_CALIBRATION_TESTS          100000\r
108 \r
109 \r
110 /****i* Component Library: Performance Counters/cl_perf_data_t\r
111 * NAME\r
112 *       cl_perf_data_t\r
113 *\r
114 * DESCRIPTION\r
115 *       The cl_perf_data_t structure is used to tracking information\r
116 *       for a single counter.\r
117 *\r
118 * SYNOPSIS\r
119 */\r
120 typedef struct _cl_perf_data\r
121 {\r
122         uint64_t                count;\r
123         uint64_t                total_time;\r
124         uint64_t                min_time;\r
125         cl_spinlock_t   lock;\r
126 \r
127 } cl_perf_data_t;\r
128 /*\r
129 * FIELDS\r
130 *       count\r
131 *               Number of samples in the counter.\r
132 *\r
133 *       total_time\r
134 *               Total time for all samples, in microseconds.\r
135 *\r
136 *       min_time\r
137 *               Minimum time for any sample in the counter, in microseconds.\r
138 *\r
139 *       lock\r
140 *               Spinlock to serialize counter updates.\r
141 *\r
142 * SEE ALSO\r
143 *       Performance Counters\r
144 *********/\r
145 \r
146 \r
147 /****i* Component Library: Performance Counters/cl_perf_t\r
148 * NAME\r
149 *       cl_perf_t\r
150 *\r
151 * DESCRIPTION\r
152 *       The cl_perf_t structure serves as a container for a group of performance\r
153 *       counters and related calibration data.\r
154 *\r
155 *       This structure should be treated as opaque and be manipulated only through\r
156 *       the provided functions.\r
157 *\r
158 * SYNOPSIS\r
159 */\r
160 typedef struct _cl_perf\r
161 {\r
162         cl_perf_data_t  *data_array;\r
163         uintn_t                 size;\r
164         uint64_t                locked_calibration_time;\r
165         uint64_t                normal_calibration_time;\r
166         cl_state_t              state;\r
167 \r
168 } cl_perf_t;\r
169 /*\r
170 * FIELDS\r
171 *       data_array\r
172 *               Pointer to the array of performance counters.\r
173 *\r
174 *       size\r
175 *               Number of counters in the counter array.\r
176 *\r
177 *       locked_calibration_time\r
178 *               Time needed to update counters while holding a spinlock.\r
179 *\r
180 *       normal_calibration_time\r
181 *               Time needed to update counters while not holding a spinlock.\r
182 *\r
183 *       state\r
184 *               State of the performance counter provider.\r
185 *\r
186 * SEE ALSO\r
187 *       Performance Counters, cl_perf_data_t\r
188 *********/\r
189 \r
190 \r
191 /****f* Component Library: Performance Counters/cl_perf_construct\r
192 * NAME\r
193 *       cl_perf_construct\r
194 *\r
195 * DESCRIPTION\r
196 *       The cl_perf_construct macro constructs a performance\r
197 *       tracking container.\r
198 *\r
199 * SYNOPSIS\r
200 */\r
201 void\r
202 cl_perf_construct(\r
203         IN      cl_perf_t* const        p_perf );\r
204 /*\r
205 * PARAMETERS\r
206 *       p_perf\r
207 *               [in] Pointer to a performance counter container to construct.\r
208 *\r
209 * RETURN VALUE\r
210 *       This function does not return a value.\r
211 *\r
212 * NOTES\r
213 *       cl_perf_construct allows calling cl_perf_destroy without first calling\r
214 *       cl_perf_init.\r
215 *\r
216 *       Calling cl_perf_construct is a prerequisite to calling any other\r
217 *       perfromance counter function except cl_perf_init.\r
218 *\r
219 *       This function is implemented as a macro and has no effect when\r
220 *       performance counters are disabled.\r
221 *\r
222 * SEE ALSO\r
223 *       Performance Counters, cl_perf_init, cl_perf_destroy\r
224 *********/\r
225 \r
226 \r
227 /****f* Component Library: Performance Counters/cl_perf_init\r
228 * NAME\r
229 *       cl_perf_init\r
230 *\r
231 * DESCRIPTION\r
232 *       The cl_perf_init function initializes a performance counter container\r
233 *       for use.\r
234 *\r
235 * SYNOPSIS\r
236 */\r
237 cl_status_t\r
238 cl_perf_init(\r
239         IN      cl_perf_t* const        p_perf,\r
240         IN      const uintn_t           num_counters );\r
241 /*\r
242 * PARAMETERS\r
243 *       p_perf\r
244 *               [in] Pointer to a performance counter container to initalize.\r
245 *\r
246 *       num_cntrs\r
247 *               [in] Number of counters to allocate in the container.\r
248 *\r
249 * RETURN VALUES\r
250 *       CL_SUCCESS if initialization was successful.\r
251 *\r
252 *       CL_INSUFFICIENT_MEMORY if there was not enough memory to initialize\r
253 *       the container.\r
254 *\r
255 *       CL_ERROR if an error was encountered initializing the locks for the\r
256 *       performance counters.\r
257 *\r
258 * NOTES\r
259 *       This function allocates all memory required for the requested number of\r
260 *       counters and initializes all locks protecting those counters.  After a\r
261 *       successful initialization, cl_perf_init calibrates the counters and\r
262 *       resets their value.\r
263 *\r
264 *       This function is implemented as a macro and has no effect when\r
265 *       performance counters are disabled.\r
266 *\r
267 * SEE ALSO\r
268 *       Performance Counters, cl_perf_construct, cl_perf_destroy, cl_perf_display\r
269 *********/\r
270 \r
271 \r
272 /****f* Component Library: Performance Counters/cl_perf_destroy\r
273 * NAME\r
274 *       cl_perf_destroy\r
275 *\r
276 * DESCRIPTION\r
277 *       The cl_perf_destroy function destroys a performance tracking container.\r
278 *\r
279 * SYNOPSIS\r
280 */\r
281 void\r
282 cl_perf_destroy(\r
283         IN      cl_perf_t* const        p_perf,\r
284         IN      const boolean_t         display );\r
285 /*\r
286 * PARAMETERS\r
287 *       p_perf\r
288 *               [in] Pointer to a performance counter container to destroy.\r
289 *\r
290 *       display\r
291 *               [in] If TRUE, causes the performance counters to be displayed.\r
292 *\r
293 * RETURN VALUE\r
294 *       This function does not return a value.\r
295 *\r
296 * NOTES\r
297 *       cl_perf_destroy frees all resources allocated in a call to cl_perf_init.\r
298 *       If the display parameter is set to TRUE, displays all counter values\r
299 *       before deallocating resources.\r
300 *\r
301 *       This function should only be called after a call to cl_perf_construct\r
302 *       or cl_perf_init.\r
303 *\r
304 *       This function is implemented as a macro and has no effect when\r
305 *       performance counters are disabled.\r
306 *\r
307 * SEE ALSO\r
308 *       Performance Counters, cl_perf_construct, cl_perf_init\r
309 *********/\r
310 \r
311 \r
312 /****f* Component Library: Performance Counters/cl_perf_reset\r
313 * NAME\r
314 *       cl_perf_reset\r
315 *\r
316 * DESCRIPTION\r
317 *       The cl_perf_reset function resets the counters contained in\r
318 *       a performance tracking container.\r
319 *\r
320 * SYNOPSIS\r
321 */\r
322 void\r
323 cl_perf_reset(\r
324         IN      cl_perf_t* const        p_perf );\r
325 /*\r
326 * PARAMETERS\r
327 *       p_perf\r
328 *               [in] Pointer to a performance counter container whose counters\r
329 *               to reset.\r
330 *\r
331 * RETURN VALUE\r
332 *       This function does not return a value.\r
333 *\r
334 * NOTES\r
335 *       This function is implemented as a macro and has no effect when\r
336 *       performance counters are disabled.\r
337 *\r
338 * SEE ALSO\r
339 *       Performance Counters\r
340 *********/\r
341 \r
342 \r
343 /****f* Component Library: Performance Counters/cl_perf_display\r
344 * NAME\r
345 *       cl_perf_display\r
346 *\r
347 * DESCRIPTION\r
348 *       The cl_perf_display function displays the current performance\r
349 *       counter values.\r
350 *\r
351 * SYNOPSIS\r
352 */\r
353 void\r
354 cl_perf_display(\r
355         IN      const cl_perf_t* const  p_perf );\r
356 /*\r
357 * PARAMETERS\r
358 *       p_perf\r
359 *               [in] Pointer to a performance counter container whose counter\r
360 *               values to display.\r
361 *\r
362 * RETURN VALUE\r
363 *       This function does not return a value.\r
364 *\r
365 * NOTES\r
366 *       This function is implemented as a macro and has no effect when\r
367 *       performance counters are disabled.\r
368 *\r
369 * SEE ALSO\r
370 *       Performance Counters, cl_perf_init\r
371 *********/\r
372 \r
373 \r
374 /****d* Component Library: Performance Counters/PERF_DECLARE\r
375 * NAME\r
376 *       PERF_DECLARE\r
377 *\r
378 * DESCRIPTION\r
379 *       The PERF_DECLARE macro declares a performance counter variable used\r
380 *       to store the starting time of a timing sequence.\r
381 *\r
382 * SYNOPSIS\r
383 *       PERF_DECLARE( index )\r
384 *\r
385 * PARAMETERS\r
386 *       index\r
387 *               [in] Index of the performance counter for which to use this\r
388 *               variable.\r
389 *\r
390 * NOTES\r
391 *       Variables should generally be declared on the stack to support\r
392 *       multi-threading.  In cases where a counter needs to be used to\r
393 *       time operations accross multiple functions, care must be taken to\r
394 *       ensure that the start time stored in this variable is not overwritten\r
395 *       before the related performance counter has been updated.\r
396 *\r
397 *       This macro has no effect when performance counters are disabled.\r
398 *\r
399 * SEE ALSO\r
400 *       Performance Counters, PERF_DECLARE_START, cl_perf_start, cl_perf_log,\r
401 *       cl_perf_stop\r
402 *********/\r
403 \r
404 \r
405 /****d* Component Library: Performance Counters/PERF_DECLARE_START\r
406 * NAME\r
407 *       PERF_DECLARE_START\r
408 *\r
409 * DESCRIPTION\r
410 *       The PERF_DECLARE_START macro declares a performance counter variable\r
411 *       and sets it to the starting time of a timed sequence.\r
412 *\r
413 * SYNOPSIS\r
414 *       PERF_DECLARE_START( index )\r
415 *\r
416 * PARAMETERS\r
417 *       index\r
418 *               [in] Index of the performance counter for which to use this\r
419 *               variable.\r
420 *\r
421 * NOTES\r
422 *       Variables should generally be declared on the stack to support\r
423 *       multi-threading.\r
424 *\r
425 *       This macro has no effect when performance counters are disabled.\r
426 *\r
427 * SEE ALSO\r
428 *       Performance Counters, PERF_DECLARE, cl_perf_start, cl_perf_log,\r
429 *       cl_perf_stop\r
430 *********/\r
431 \r
432 \r
433 /****d* Component Library: Performance Counters/cl_perf_start\r
434 * NAME\r
435 *       cl_perf_start\r
436 *\r
437 * DESCRIPTION\r
438 *       The cl_perf_start macro sets the starting value of a timed sequence.\r
439 *\r
440 * SYNOPSIS\r
441 */\r
442 void\r
443 cl_perf_start(\r
444         IN      const uintn_t index );\r
445 /*\r
446 * PARAMETERS\r
447 *       index\r
448 *               [in] Index of the performance counter to set.\r
449 *\r
450 * NOTES\r
451 *       This macro has no effect when performance counters are disabled.\r
452 *\r
453 * SEE ALSO\r
454 *       Performance Counters, PERF_DECLARE, PERF_DECLARE_START, cl_perf_log,\r
455 *       cl_perf_update, cl_perf_stop\r
456 *********/\r
457 \r
458 \r
459 /****d* Component Library: Performance Counters/cl_perf_clr\r
460 * NAME\r
461 *       cl_perf_clr\r
462 *\r
463 * DESCRIPTION\r
464 *       The cl_perf_clr macro clears a counter variable.\r
465 *\r
466 * SYNOPSIS\r
467 */\r
468 void\r
469 cl_perf_inc(\r
470         IN      const uintn_t index );\r
471 /*\r
472 * PARAMETERS\r
473 *       index\r
474 *               [in] Index of the performance counter to set.\r
475 *\r
476 * NOTES\r
477 *       This macro has no effect when performance counters are disabled.\r
478 *\r
479 * SEE ALSO\r
480 *       Performance Counters, PERF_DECLARE, PERF_DECLARE_START, cl_perf_log,\r
481 *       cl_perf_update, cl_perf_stop\r
482 *********/\r
483 \r
484 \r
485 /****d* Component Library: Performance Counters/cl_perf_inc\r
486 * NAME\r
487 *       cl_perf_inc\r
488 *\r
489 * DESCRIPTION\r
490 *       The cl_perf_inc macro increments a counter variable by one.\r
491 *\r
492 * SYNOPSIS\r
493 */\r
494 void\r
495 cl_perf_inc(\r
496         IN      const uintn_t index );\r
497 /*\r
498 * PARAMETERS\r
499 *       index\r
500 *               [in] Index of the performance counter to set.\r
501 *\r
502 * NOTES\r
503 *       This macro has no effect when performance counters are disabled.\r
504 *\r
505 * SEE ALSO\r
506 *       Performance Counters, PERF_DECLARE, PERF_DECLARE_START, cl_perf_log,\r
507 *       cl_perf_update, cl_perf_stop\r
508 *********/\r
509 \r
510 \r
511 /****d* Component Library: Performance Counters/cl_perf_update\r
512 * NAME\r
513 *       cl_perf_update\r
514 *\r
515 * DESCRIPTION\r
516 *       The cl_perf_update macro adds a timing sample based on a provided start\r
517 *       time to a counter in a performance counter container.\r
518 *\r
519 * SYNOPSIS\r
520 */\r
521 void\r
522 cl_perf_update(\r
523         IN      cl_perf_t* const        p_perf,\r
524         IN      const uintn_t           index,\r
525         IN      const uint64_t          start_time );\r
526 /*\r
527 * PARAMETERS\r
528 *       p_perf\r
529 *               [in] Pointer to a performance counter container to whose counter\r
530 *               the sample should be added.\r
531 *\r
532 *       index\r
533 *               [in] Number of the performance counter to update with a new sample.\r
534 *\r
535 *       start_time\r
536 *               [in] Timestamp to use as the start time for the timing sample.\r
537 *\r
538 * RETURN VALUE\r
539 *       This function does not return a value.\r
540 *\r
541 * NOTES\r
542 *       This macro has no effect when performance counters are disabled.\r
543 *\r
544 * SEE ALSO\r
545 *       Performance Counters, PERF_DECLARE, PERF_DECLARE_START, cl_perf_start,\r
546 *       cl_perf_lob, cl_perf_stop\r
547 *********/\r
548 \r
549 \r
550 /****d* Component Library: Performance Counters/cl_perf_update_ctr\r
551 * NAME\r
552 *       cl_perf_update_ctr\r
553 *\r
554 * DESCRIPTION\r
555 *       The cl_perf_update_ctr macro updates a counter in a performance\r
556 *       counter container.\r
557 *\r
558 * SYNOPSIS\r
559 */\r
560 void\r
561 cl_perf_update_ctr(\r
562         IN      cl_perf_t* const        p_perf,\r
563         IN      const uintn_t           index );\r
564 /*\r
565 * PARAMETERS\r
566 *       p_perf\r
567 *               [in] Pointer to a performance counter container to whose counter\r
568 *               the sample should be added.\r
569 *\r
570 *       index\r
571 *               [in] Number of the performance counter to update with a new sample.\r
572 *\r
573 * RETURN VALUE\r
574 *       This function does not return a value.\r
575 *\r
576 * NOTES\r
577 *       This macro has no effect when performance counters are disabled.\r
578 *\r
579 * SEE ALSO\r
580 *       Performance Counters, PERF_DECLARE, PERF_DECLARE_START, cl_perf_start,\r
581 *       cl_perf_lob, cl_perf_stop\r
582 *********/\r
583 \r
584 \r
585 /****d* Component Library: Performance Counters/cl_perf_log\r
586 * NAME\r
587 *       cl_perf_log\r
588 *\r
589 * DESCRIPTION\r
590 *       The cl_perf_log macro adds a given timing sample to a\r
591 *       counter in a performance counter container.\r
592 *\r
593 * SYNOPSIS\r
594 */\r
595 void\r
596 cl_perf_log(\r
597         IN      cl_perf_t* const        p_perf,\r
598         IN      const uintn_t           index,\r
599         IN      const uint64_t          pc_total_time );\r
600 /*\r
601 * PARAMETERS\r
602 *       p_perf\r
603 *               [in] Pointer to a performance counter container to whose counter\r
604 *               the sample should be added.\r
605 *\r
606 *       index\r
607 *               [in] Number of the performance counter to update with a new sample.\r
608 *\r
609 *       pc_total_time\r
610 *               [in] Total elapsed time for the sample being added.\r
611 *\r
612 * RETURN VALUE\r
613 *       This function does not return a value.\r
614 *\r
615 * NOTES\r
616 *       This macro has no effect when performance counters are disabled.\r
617 *\r
618 * SEE ALSO\r
619 *       Performance Counters, PERF_DECLARE, PERF_DECLARE_START, cl_perf_start,\r
620 *       cl_perf_update, cl_perf_stop\r
621 *********/\r
622 \r
623 \r
624 /****d* Component Library: Performance Counters/cl_perf_stop\r
625 * NAME\r
626 *       cl_perf_stop\r
627 *\r
628 * DESCRIPTION\r
629 *       The cl_perf_log macro updates a counter in a performance counter\r
630 *       container with a new timing sample.\r
631 *\r
632 * SYNOPSIS\r
633 */\r
634 void\r
635 cl_perf_stop(\r
636         IN      cl_perf_t* const        p_perf,\r
637         IN      const uintn_t           index );\r
638 /*\r
639 * PARAMETERS\r
640 *       p_perf\r
641 *               [in] Pointer to a performance counter container to whose counter\r
642 *               a sample should be added.\r
643 *\r
644 *       index\r
645 *               [in] Number of the performance counter to update with a new sample.\r
646 *\r
647 * RETURN VALUE\r
648 *       This function does not return a value.\r
649 *\r
650 * NOTES\r
651 *       The ending time stamp is taken and elapsed time calculated before updating\r
652 *       the specified counter.\r
653 *\r
654 *       This macro has no effect when performance counters are disabled.\r
655 *\r
656 * SEE ALSO\r
657 *       Performance Counters, PERF_DECLARE, PERF_DECLARE_START, cl_perf_start,\r
658 *       cl_perf_log\r
659 *********/\r
660 \r
661 \r
662 /*\r
663  * PERF_TRACK_ON must be defined by the user before including this file to\r
664  * enable performance tracking.  To disable tracking, users should undefine\r
665  * PERF_TRACK_ON.\r
666  */\r
667 #if defined( PERF_TRACK_ON )\r
668 /*\r
669  * Enable performance tracking.\r
670  */\r
671 \r
672 #define cl_perf_construct( p_perf ) \\r
673         __cl_perf_construct( p_perf )\r
674 #define cl_perf_init( p_perf, num_counters ) \\r
675         __cl_perf_init( p_perf, num_counters )\r
676 #define cl_perf_destroy( p_perf, display ) \\r
677         __cl_perf_destroy( p_perf, display )\r
678 #define cl_perf_reset( p_perf ) \\r
679         __cl_perf_reset( p_perf )\r
680 #define cl_perf_display( p_perf ) \\r
681         __cl_perf_display( p_perf )\r
682 #define PERF_DECLARE( index ) \\r
683         uint64_t Pc##index\r
684 #define PERF_DECLARE_START( index ) \\r
685         uint64 Pc##index = cl_get_time_stamp()\r
686 #define cl_perf_start( index ) \\r
687         (Pc##index = cl_get_time_stamp())\r
688 #define cl_perf_clr( index ) \\r
689         (Pc##index = 0)\r
690 #define cl_perf_inc( index ) \\r
691         (Pc##index++)\r
692 #define cl_perf_log( p_perf, index, pc_total_time ) \\r
693 {\\r
694         /* Update the performance data.  This requires synchronization. */ \\r
695         cl_spinlock_acquire( &((cl_perf_t*)p_perf)->data_array[index].lock ); \\r
696         \\r
697         ((cl_perf_t*)p_perf)->data_array[index].total_time += pc_total_time; \\r
698         ((cl_perf_t*)p_perf)->data_array[index].count++; \\r
699         if( pc_total_time < ((cl_perf_t*)p_perf)->data_array[index].min_time ) \\r
700                 ((cl_perf_t*)p_perf)->data_array[index].min_time = pc_total_time; \\r
701         \\r
702         cl_spinlock_release( &((cl_perf_t*)p_perf)->data_array[index].lock );  \\r
703 }\r
704 #define cl_perf_update( p_perf, index, start_time )     \\r
705 {\\r
706         /* Get the ending time stamp, and calculate the total time. */ \\r
707         uint64_t pc_total_time = cl_get_time_stamp() - start_time;\\r
708         /* Using stack variable for start time, stop and log  */ \\r
709         cl_perf_log( p_perf, index, pc_total_time ); \\r
710 }\r
711 #define cl_perf_update_ctr( p_perf, index )     \\r
712         cl_perf_log( p_perf, index, Pc##index )\r
713 #define cl_perf_stop( p_perf, index ) \\r
714 {\\r
715         cl_perf_update( p_perf, index, Pc##index );\\r
716 }\r
717 \r
718 #define cl_get_perf_values( p_perf, index, p_total, p_min, p_count )    \\r
719 {\\r
720         *p_total = p_perf->data_array[index].total_time;        \\r
721         *p_min = p_perf->data_array[index].min_time;            \\r
722         *p_count = p_perf->data_array[index].count;                     \\r
723 }\r
724 \r
725 #define cl_get_perf_calibration( p_perf, p_locked_time, p_normal_time ) \\r
726 {\\r
727         *p_locked_time = p_perf->locked_calibration_time;       \\r
728         *p_normal_time = p_perf->normal_calibration_time;       \\r
729 }\r
730 \r
731 #define cl_get_perf_string( p_perf, i ) \\r
732 "CL Perf:\t%lu\t%"PRIu64"\t%"PRIu64"\t%"PRIu64"\n",     \\r
733                         i, p_perf->data_array[i].total_time,    \\r
734                         p_perf->data_array[i].min_time, p_perf->data_array[i].count\r
735 \r
736 #else   /* PERF_TRACK_ON */\r
737 /*\r
738  * Disable performance tracking.\r
739  */\r
740 \r
741 #define cl_perf_construct( p_perf )\r
742 #define cl_perf_init( p_perf, num_cntrs )               CL_SUCCESS\r
743 #define cl_perf_destroy( p_perf, display )\r
744 #define cl_perf_reset( p_perf )\r
745 #define cl_perf_display( p_perf )\r
746 #define PERF_DECLARE( index )\r
747 #define PERF_DECLARE_START( index )\r
748 #define cl_perf_start( index )\r
749 #define cl_perf_clr( index )\r
750 #define cl_perf_inc( index )\r
751 #define cl_perf_log( p_perf, index, pc_total_time )\r
752 #define cl_perf_update( p_perf, index, start_time )\r
753 #define cl_perf_update_ctr( p_perf, index )\r
754 #define cl_perf_stop( p_perf, index )\r
755 #define cl_get_perf_values( p_perf, index, p_total, p_min, p_count )\r
756 #define cl_get_perf_calibration( p_perf, p_locked_time, p_normal_time )\r
757 #endif  /* PERF_TRACK_ON */\r
758 \r
759 \r
760 /*\r
761  * Internal performance tracking functions.  Users should never call these\r
762  * functions directly.  Instead, use the macros defined above to resolve\r
763  * to these functions when PERF_TRACK_ON is defined, which allows disabling\r
764  * performance tracking.\r
765  */\r
766 \r
767 \r
768 /*\r
769  * Initialize the state of the performance tracking structure.\r
770  */\r
771 CL_EXPORT void CL_API\r
772 __cl_perf_construct(\r
773         IN      cl_perf_t* const                p_perf );\r
774 \r
775 /*\r
776  * Size the performance tracking information and initialize all\r
777  * related structures.\r
778  */\r
779 CL_EXPORT cl_status_t CL_API\r
780 __cl_perf_init(\r
781         IN      cl_perf_t* const                p_perf,\r
782         IN      const uintn_t                   num_counters );\r
783 \r
784 /*\r
785  * Destroy the performance tracking data.\r
786  */\r
787 CL_EXPORT void CL_API\r
788 __cl_perf_destroy(\r
789         IN      cl_perf_t* const                p_perf,\r
790         IN      const boolean_t                 display );\r
791 \r
792 /*\r
793  * Reset the performance tracking data.\r
794  */\r
795 CL_EXPORT void CL_API\r
796 __cl_perf_reset(\r
797         IN      cl_perf_t* const                p_perf );\r
798 \r
799 /*\r
800  * Display the current performance tracking data.\r
801  */\r
802 CL_EXPORT void CL_API\r
803 __cl_perf_display(\r
804         IN      const cl_perf_t* const  p_perf );\r
805 \r
806 \r
807 #endif  /* _CL_PERF_H_ */\r