home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / sdktools / winnt / perfmon / counters.c < prev    next >
C/C++ Source or Header  |  1996-06-12  |  27KB  |  932 lines

  1. /*++ BUILD Version: 0001    // Increment this if a change has global effects
  2.  
  3. Copyright (c) 1992-1996   Microsoft Corporation
  4.  
  5. Module Name:
  6.  
  7.     counters.c  
  8.  
  9. Abstract:
  10.  
  11.     This module contains the routines to calculate "DataPoint" values from
  12.     the registry data.
  13.  
  14.     The algoritms were lifted from RussBls's "Data.C" in winmeter.
  15.  
  16.     All the math is done in floating point to get the correct results, at
  17.     the sacrifice of efficiency on a 386 with not 387. We can always
  18.     revisit these routines later.
  19.  
  20. Revision History:
  21.  
  22.     Bob Watson  11/04/92
  23.         -- modified calculations to use more integer math and "early
  24.             exits" to improve efficiency on slower & non-coprocessor
  25.             machines
  26. --*/
  27.  
  28. //==========================================================================//
  29. //                                  Includes                                //
  30. //==========================================================================//
  31.  
  32.  
  33. #include "perfmon.h"       // perfmon include files
  34. #include "counters.h"      // Exported declarations for this file
  35.  
  36.  
  37. //==========================================================================//
  38. //                                  Constants                               //
  39. //==========================================================================//
  40.  
  41.  
  42. #define INVERT             PERF_COUNTER_TIMER_INV
  43. #define NS100_INVERT       PERF_100NSEC_TIMER_INV
  44. #define NS100              PERF_100NSEC_TIMER
  45. #define TIMER_MULTI        PERF_COUNTER_MULTI_TIMER
  46. #define TIMER_MULTI_INVERT PERF_COUNTER_MULTI_TIMER_INV
  47. #define NS100_MULTI        PERF_100NSEC_MULTI_TIMER
  48. #define NS100_MULTI_INVERT PERF_100NSEC_MULTI_TIMER_INV
  49.  
  50.  
  51. #define FRACTION 1
  52. #define BULK     1
  53.  
  54. #define TOO_BIG   (FLOAT)1500000000
  55.  
  56. //==========================================================================//
  57. //                              Local Functions                             //
  58. //==========================================================================//
  59.  
  60.  
  61.  
  62. FLOAT
  63. eGetTimeInterval(
  64.     IN LONGLONG *pliCurrentTime,
  65.     IN LONGLONG *pliPreviousTime,
  66.     IN LONGLONG *pliFreq
  67. )
  68. /*++
  69.  
  70. Routine Description:
  71.  
  72.     Get the difference between the current and previous time counts,
  73.         then divide by the frequency.
  74.     
  75. Arguments:
  76.  
  77.     IN pCurrentTime
  78.     IN pPreviousTime
  79.         used to compute the duration of this sample (the time between
  80.         samples
  81.  
  82.     IN pliFreq
  83.         # of  counts (clock ticks) per second
  84.  
  85. Return Value:
  86.  
  87.     Floating point representation of Time Interval (seconds)
  88. --*/
  89. {
  90.     FLOAT   eTimeDifference;
  91.     FLOAT   eFreq;
  92.     FLOAT   eTimeInterval ;
  93.  
  94.     LONGLONG liDifference;
  95.  
  96.     // Get the number of counts that have occured since the last sample
  97.  
  98.     liDifference = *pliCurrentTime - *pliPreviousTime;
  99.  
  100.     if (liDifference <= (LONGLONG)0) {
  101.         return (FLOAT) 0.0f;
  102.     } else {
  103.         eTimeDifference = (FLOAT)liDifference;
  104.  
  105.         // Get the counts per second
  106.  
  107.         eFreq = (FLOAT)(*pliFreq) ;
  108.         if (eFreq <= 0.0f)
  109.            return (FLOAT) 0.0f;
  110.  
  111.         // Get the time since the last sample.
  112.  
  113.         eTimeInterval = eTimeDifference / eFreq ;
  114.  
  115.         return (eTimeInterval) ;
  116.     }
  117. } // eGetTimeInterval
  118.  
  119. FLOAT
  120. Counter_Counter_Common(
  121.     IN PLINESTRUCT pLineStruct,
  122.     IN INT iType
  123. )
  124. /*++
  125.  
  126. Routine Description:
  127.  
  128.     Take the difference between the current and previous counts
  129.         then divide by the time interval
  130.     
  131. Arguments:
  132.  
  133.     IN pLineStruct
  134.         Line structure containing data to perform computations on
  135.  
  136.     IN iType
  137.         Counter Type
  138.         
  139.  
  140. Return Value:
  141.  
  142.     Floating point representation of outcome
  143. --*/
  144. {
  145.     FLOAT   eTimeInterval;
  146.     FLOAT   eDifference;
  147.     FLOAT   eCount ;
  148.     BOOL    bValueDrop = FALSE ;
  149.  
  150.     LONGLONG   liDifference;
  151.  
  152.     if (iType != BULK) {
  153.  
  154.         // check if it is too big to be a wrap-around case
  155.         if (pLineStruct->lnaCounterValue[0] <
  156.             pLineStruct->lnaOldCounterValue[0])
  157.            {
  158.            if (pLineStruct->lnaCounterValue[0] -
  159.                pLineStruct->lnaOldCounterValue[0] > (DWORD)0x00ffff0000)
  160.               {
  161.               return (FLOAT) 0.0f;
  162.               }
  163.            bValueDrop = TRUE ;
  164.            }
  165.  
  166.         liDifference = pLineStruct->lnaCounterValue[0] -
  167.                        pLineStruct->lnaOldCounterValue[0];
  168.  
  169.         liDifference &= (DWORD)(0x0ffffffff);
  170.  
  171.     } else {
  172.         liDifference = pLineStruct->lnaCounterValue[0] -
  173.                        pLineStruct->lnaOldCounterValue[0];
  174.     }
  175.     
  176.     if (liDifference <= (LONGLONG) 0) {
  177.         return (FLOAT) 0.0f;
  178.     } else {
  179.         eTimeInterval = eGetTimeInterval(&pLineStruct->lnNewTime,
  180.                                         &pLineStruct->lnOldTime,
  181.                                         &pLineStruct->lnPerfFreq) ;
  182.         if (eTimeInterval <= 0.0f) {
  183.             return (FLOAT) 0.0f;
  184.         } else {
  185.             eDifference = (FLOAT)(liDifference);
  186.  
  187.             eCount         = eDifference / eTimeInterval ;
  188.             
  189.             if (bValueDrop && eCount > (FLOAT) TOO_BIG) {
  190.                 // ignore this bogus data since it is too big for 
  191.                 // the wrap-around case
  192.                 eCount = (FLOAT) 0.0f ;
  193.             }
  194.             return(eCount) ;
  195.         }
  196.     }
  197. } // Counter_Counter_Common
  198.  
  199.  
  200. FLOAT
  201. Counter_Average_Timer(
  202.     IN PLINESTRUCT pLineStruct
  203. )
  204. /*++
  205.  
  206. Routine Description:
  207.  
  208.     Take the differences between the current and previous times and counts
  209.     divide the time interval by the counts multiply by 10,000,000 (convert
  210.     from 100 nsec to sec)
  211.     
  212. Arguments:
  213.  
  214.     IN pLineStruct
  215.         Line structure containing data to perform computations on
  216.  
  217. Return Value:
  218.  
  219.     Floating point representation of outcome
  220. --*/
  221. {
  222.     FLOAT   eTimeInterval;
  223.     FLOAT   eCount;
  224.  
  225.     LONGLONG    liDifference;
  226.  
  227.     // Get the current and previous counts.
  228.  
  229.     liDifference = (DWORD)pLineStruct->lnaCounterValue[1] - 
  230.             (DWORD)pLineStruct->lnaOldCounterValue[1];
  231.  
  232.     if ( liDifference <= 0) {
  233.         return (FLOAT) 0.0f;
  234.     } else {
  235.         // Get the amount of time that has passed since the last sample
  236.         eTimeInterval = eGetTimeInterval(&pLineStruct->lnaCounterValue[0],
  237.                                             &pLineStruct->lnaOldCounterValue[0],
  238.                                             &pLineStruct->lnPerfFreq) ;
  239.  
  240.         if (eTimeInterval < 0.0f) { // return 0 if negative time has passed
  241.             return (0.0f);
  242.         } else {
  243.             // Get the number of counts in this time interval.
  244.             eCount = eTimeInterval / (FLOAT)(liDifference);
  245.             return(eCount) ;
  246.         }
  247.     }
  248. } //Counter_Average_Timer
  249.  
  250.  
  251.  
  252. FLOAT
  253. Counter_Average_Bulk(
  254.     IN PLINESTRUCT pLineStruct
  255. )
  256. /*++
  257.  
  258. Routine Description:
  259.  
  260.     Take the differences between the current and previous byte counts and
  261.     operation counts divide the bulk count by the operation counts
  262.     
  263. Arguments:
  264.  
  265.     IN pLineStruct
  266.         Line structure containing data to perform computations on
  267.  
  268. Return Value:
  269.  
  270.     Floating point representation of outcome
  271. --*/
  272. {
  273.     FLOAT   eBulkDelta;
  274.     FLOAT   eDifference;
  275.     FLOAT   eCount;
  276.  
  277.     LONGLONG liDifference;
  278.     LONGLONG liBulkDelta;
  279.  
  280.     // Get the bulk count increment since the last sample
  281.  
  282.     liBulkDelta = pLineStruct->lnaCounterValue[0] -
  283.             pLineStruct->lnaOldCounterValue[0];
  284.  
  285.     if (liBulkDelta <= (LONGLONG) 0) {
  286.         return (FLOAT) 0.0f;
  287.     } else {
  288.         // Get the current and previous counts.
  289.         liDifference = (DWORD)pLineStruct->lnaCounterValue[1] -
  290.                 (DWORD) pLineStruct->lnaOldCounterValue[1];
  291.         liDifference &= (DWORD) (0x0ffffffff);
  292.  
  293.         // Get the number of counts in this time interval.
  294.  
  295.         if ( liDifference <= (LONGLONG) 0) {
  296.             // Counter value invalid
  297.             return (FLOAT) 0.0f;
  298.         } else {
  299.             eBulkDelta = (FLOAT) (liBulkDelta);
  300.             eDifference = (FLOAT) (liDifference);
  301.             eCount = eBulkDelta / eDifference ;
  302.  
  303.             // Scale the value to up to 1 second
  304.  
  305.             return(eCount) ;
  306.         }
  307.     }
  308. } // Counter_Average_Bulk
  309.  
  310.  
  311.  
  312. FLOAT
  313. Counter_Timer_Common(
  314.     IN  PLINESTRUCT pLineStruct,
  315.     IN  INT iType
  316. )
  317. /*++
  318.  
  319. Routine Description:
  320.  
  321.     Take the difference between the current and previous counts,
  322.         Normalize the count (counts per interval)
  323.         divide by the time interval (count = % of interval)
  324.         if (invert)
  325.             subtract from 1 (the normalized size of an interval)
  326.         multiply by 100 (convert to a percentage)
  327.         this value from 100.
  328.     
  329. Arguments:
  330.  
  331.     IN pLineStruct
  332.         Line structure containing data to perform computations on
  333.  
  334.     IN iType
  335.         Counter Type
  336.  
  337. Return Value:
  338.  
  339.     Floating point representation of outcome
  340. --*/
  341. {
  342.     FLOAT   eTimeInterval;
  343.     FLOAT   eDifference;
  344.     FLOAT   eFreq;
  345.     FLOAT   eFraction;
  346.     FLOAT   eMultiBase;
  347.     FLOAT   eCount ;
  348.  
  349.     LONGLONG   liTimeInterval;
  350.     LONGLONG   liDifference;
  351.  
  352.     // Get the amount of time that has passed since the last sample
  353.  
  354.     if (iType == NS100 ||
  355.         iType == NS100_INVERT ||
  356.         iType == NS100_MULTI ||
  357.         iType == NS100_MULTI_INVERT) {
  358.             liTimeInterval = pLineStruct->lnNewTime100Ns -
  359.                 pLineStruct->lnOldTime100Ns ;
  360.             eTimeInterval = (FLOAT) (liTimeInterval);
  361.     } else {
  362.             eTimeInterval = eGetTimeInterval(&pLineStruct->lnNewTime,
  363.                                             &pLineStruct->lnOldTime,
  364.                                             &pLineStruct->lnPerfFreq) ;
  365.     }
  366.  
  367.     if (eTimeInterval <= 0.0f)
  368.        return (FLOAT) 0.0f;
  369.  
  370.     // Get the current and previous counts.
  371.  
  372.     liDifference = pLineStruct->lnaCounterValue[0] -
  373.             pLineStruct->lnaOldCounterValue[0] ;
  374.  
  375.     // Get the number of counts in this time interval.
  376.     // (1, 2, 3 or any number of seconds could have gone by since
  377.     // the last sample)
  378.  
  379.     eDifference = (FLOAT) (liDifference) ;
  380.  
  381.     if (iType == 0 || iType == INVERT)
  382.     {
  383.         // Get the counts per interval (second)
  384.  
  385.         eFreq = (FLOAT) (pLineStruct->lnPerfFreq) ;
  386.         if (eFreq <= 0.0f)
  387.            return (FLOAT) 0.0f;
  388.  
  389.         // Calculate the fraction of the counts that are used by whatever
  390.         // we are measuring
  391.  
  392.         eFraction = eDifference / eFreq ;
  393.     }
  394.     else
  395.     {
  396.         eFraction = eDifference ;
  397.     }
  398.  
  399.     // Calculate the fraction of time used by what were measuring.
  400.  
  401.     eCount = eFraction / eTimeInterval ;
  402.  
  403.     // If this is  an inverted count take care of the inversion.
  404.  
  405.     if (iType == INVERT || iType == NS100_INVERT)
  406.         eCount = (FLOAT) 1.0 - eCount ;
  407.  
  408.     // If this is  an inverted multi count take care of the inversion.
  409.  
  410.     if (iType == TIMER_MULTI_INVERT || iType == NS100_MULTI_INVERT) {
  411.         eMultiBase  = (FLOAT)pLineStruct->lnaCounterValue[1] ;
  412.         eCount = (FLOAT) eMultiBase - eCount ;
  413.     }
  414.  
  415.     // Scale the value to up to 100.
  416.  
  417.     eCount *= 100.0f ;
  418.  
  419.     if (eCount < 0.0f) eCount = 0.0f ;
  420.  
  421.     if (eCount > 100.0f &&
  422.         iType != NS100_MULTI &&
  423.         iType != NS100_MULTI_INVERT &&
  424.         iType != TIMER_MULTI &&
  425.         iType != TIMER_MULTI_INVERT) {
  426.  
  427.         eCount = 100.0f;
  428.     }
  429.  
  430.     return(eCount) ;
  431. } // Counter_Timer_Common
  432.  
  433.  
  434. FLOAT
  435. Counter_Raw_Fraction(
  436.     IN PLINESTRUCT pLineStruct
  437. )
  438. /*++
  439.  
  440. Routine Description:
  441.  
  442.     Evaluate a raw fraction (no time, just two values: Numerator and
  443.         Denominator) and multiply by 100 (to make a percentage;
  444.  
  445. Arguments:
  446.  
  447.     IN pLineStruct
  448.         Line structure containing data to perform computations on
  449.  
  450. Return Value:
  451.  
  452.     Floating point representation of outcome
  453. --*/
  454. {
  455.     FLOAT   eCount ;
  456.  
  457.     LONGLONG   liNumerator;
  458.  
  459.     if ( pLineStruct->lnaCounterValue[0] == 0 ||
  460.             pLineStruct->lnaCounterValue[1] == 0 ) {
  461.         // invalid value
  462.         return (0.0f);
  463.     } else {
  464.         liNumerator = pLineStruct->lnaCounterValue[0] * 100;
  465.         eCount = (FLOAT) (liNumerator)  /
  466.                  (FLOAT) pLineStruct->lnaCounterValue[1];
  467.         return(eCount) ;
  468.     }
  469. } // Counter_Raw_Fraction
  470.  
  471.  
  472. FLOAT
  473. eElapsedTime(
  474.     PLINESTRUCT pLineStruct,
  475.     INT iType
  476. )
  477. /*++
  478.  
  479. Routine Description:
  480.  
  481.     Converts 100NS elapsed time to fractional seconds
  482.  
  483. Arguments:
  484.  
  485.     IN pLineStruct
  486.         Line structure containing data to perform computations on
  487.  
  488.     IN iType
  489.         Unused.
  490.  
  491. Return Value:
  492.  
  493.     Floating point representation of elapsed time in seconds
  494. --*/
  495. {
  496.     FLOAT   eSeconds ;
  497.  
  498.     LONGLONG   liDifference;
  499.  
  500.     if (pLineStruct->lnaCounterValue[0] <= (LONGLONG) 0) {
  501.         // no data [start time = 0] so return 0
  502.         return (FLOAT) 0.0f;
  503.     } else {
  504.         LONGLONG PerfFreq;
  505.        
  506.         PerfFreq = *(LONGLONG UNALIGNED *)(&pLineStruct->lnObject.PerfFreq) ;
  507.  
  508.         // otherwise compute difference between current time and start time
  509.         liDifference = 
  510.             pLineStruct->lnNewTime - pLineStruct->lnaCounterValue[0];
  511.  
  512.         if (liDifference <= (LONGLONG) 0 ||
  513.             PerfFreq <= 0) {
  514.             return (FLOAT) 0.0f;
  515.         } else {
  516.             // convert to fractional seconds using object counter
  517.             eSeconds = (FLOAT) (liDifference) /
  518.                 (FLOAT) (PerfFreq);
  519.  
  520.             return (eSeconds);
  521.         }
  522.     }
  523.     
  524. } // eElapsedTime
  525.  
  526.  
  527. FLOAT
  528. Sample_Common(
  529.     PLINESTRUCT pLineStruct,
  530.     INT iType
  531. )
  532. /*++
  533.  
  534. Routine Description:
  535.  
  536.     Divites "Top" differenced by Base Difference
  537.  
  538. Arguments:
  539.  
  540.     IN pLineStruct
  541.         Line structure containing data to perform computations on
  542.  
  543.     IN iType
  544.         Counter Type
  545.  
  546. Return Value:
  547.  
  548.     Floating point representation of outcome
  549. --*/
  550. {
  551.     FLOAT   eCount ;
  552.  
  553.     LONG    lDifference;
  554.     LONG    lBaseDifference;
  555.  
  556.     lDifference = (DWORD)pLineStruct->lnaCounterValue[0] -
  557.         (DWORD)pLineStruct->lnaOldCounterValue[0] ;
  558.     lDifference &= (DWORD) (0x0ffffffff);
  559.  
  560.     if (lDifference <= 0) {
  561.         return (FLOAT) 0.0f;
  562.     } else {
  563.         lBaseDifference = (DWORD)pLineStruct->lnaCounterValue[1] -
  564.             (DWORD)pLineStruct->lnaOldCounterValue[1] ;
  565.  
  566.         if ( lBaseDifference <= 0 ) {
  567.             // invalid value
  568.             return (0.0f);
  569.         } else {
  570.             eCount = (FLOAT)lDifference / (FLOAT)lBaseDifference ;
  571.  
  572.             if (iType == FRACTION) {
  573.                 eCount *= (FLOAT) 100.0f ;
  574.             }
  575.             return(eCount) ;
  576.         }
  577.     }
  578. } // Sample_Common
  579.  
  580.  
  581. //==========================================================================//
  582. //                             Exported Functions                           //
  583. //==========================================================================//
  584.  
  585.  
  586. /*****************************************************************************
  587.  * Counter_Counter - Take the difference between the current and previous
  588.  *                   counts then divide by the time interval
  589.  ****************************************************************************/
  590. #define Counter_Counter(pLineStruct)      \
  591.         Counter_Counter_Common(pLineStruct, 0)
  592. #if 0
  593. FLOAT Counter_Counter(PLINESTRUCT pLineStruct)
  594. {
  595.         return Counter_Counter_Common(pLineStruct, 0) ;
  596. }
  597. #endif
  598.  
  599. /*****************************************************************************
  600.  * Counter_Bulk    - Take the difference between the current and previous
  601.  *                   counts then divide by the time interval
  602.  *                   Same as a Counter_counter except it uses lognlong
  603.  ****************************************************************************/
  604. #define Counter_Bulk(pLineStruct)         \
  605.         Counter_Counter_Common(pLineStruct, BULK)
  606. #if 0
  607. FLOAT Counter_Bulk(PLINESTRUCT pLineStruct)
  608. {
  609.         return Counter_Counter_Common(pLineStruct, BULK) ;
  610. }
  611. #endif
  612.  
  613.  
  614. /*****************************************************************************
  615.  * Counter_Timer100Ns -
  616.  *
  617.  *      Need to review with RussBl exactly what he is doing here.
  618.  ****************************************************************************/
  619. #define Counter_Timer100Ns(pLineStruct)     \
  620.         Counter_Timer_Common(pLineStruct, NS100)
  621. #if 0
  622. FLOAT Counter_Timer100Ns(PLINESTRUCT pLineStruct)
  623. {
  624.         return Counter_Timer_Common(pLineStruct, NS100) ;
  625. }
  626. #endif
  627.  
  628. /*****************************************************************************
  629.  * Counter_Timer100Ns_Inv -
  630.  *
  631.  *      Need to review with RussBl exactly what he is doing here.
  632.  ****************************************************************************/
  633. #define Counter_Timer100Ns_Inv(pLineStruct)     \
  634.         Counter_Timer_Common(pLineStruct, NS100_INVERT)
  635. #if 0
  636. FLOAT Counter_Timer100Ns_Inv(PLINESTRUCT pLineStruct)
  637. {
  638.         return Counter_Timer_Common(pLineStruct, NS100_INVERT) ;
  639.  
  640. }
  641. #endif
  642.  
  643. /*****************************************************************************
  644.  * Counter_Timer_Multi -
  645.  *
  646.  *      Need to review with RussBl exactly what he is doing here.
  647.  ****************************************************************************/
  648. #define Counter_Timer_Multi(pLineStruct)     \
  649.         Counter_Timer_Common(pLineStruct, TIMER_MULTI)
  650. #if 0
  651. FLOAT Counter_Timer_Multi(PLINESTRUCT pLineStruct)
  652. {
  653.         return Counter_Timer_Common(pLineStruct, TIMER_MULTI) ;
  654. }
  655. #endif
  656.  
  657. /*****************************************************************************
  658.  * Counter_Timer_Multi_Inv -
  659.  *
  660.  *      Need to review with RussBl exactly what he is doing here.
  661.  ****************************************************************************/
  662. #define Counter_Timer_Multi_Inv(pLineStruct)       \
  663.         Counter_Timer_Common(pLineStruct, TIMER_MULTI_INVERT)
  664. #if 0
  665. FLOAT Counter_Timer_Multi_Inv(PLINESTRUCT pLineStruct)
  666. {
  667.         return Counter_Timer_Common(pLineStruct, TIMER_MULTI_INVERT) ;
  668. }
  669. #endif
  670.  
  671.  
  672. /*****************************************************************************
  673.  * Counter_Timer100Ns_Multi -
  674.  *
  675.  *      Need to review with RussBl exactly what he is doing here.
  676.  ****************************************************************************/
  677. #define Counter_Timer100Ns_Multi(pLineStruct)     \
  678.         Counter_Timer_Common(pLineStruct, NS100_MULTI)
  679. #if 0
  680. FLOAT Counter_Timer100Ns_Multi(PLINESTRUCT pLineStruct)
  681. {
  682.         return Counter_Timer_Common(pLineStruct, NS100_MULTI) ;
  683. }
  684. #endif
  685.  
  686. /*****************************************************************************
  687.  * Counter_Timer100Ns_Multi_Inv -
  688.  *
  689.  *      Need to review with RussBl exactly what he is doing here.
  690.  ****************************************************************************/
  691. #define Counter_Timer100Ns_Multi_Inv(pLineStruct)    \
  692.         Counter_Timer_Common(pLineStruct, NS100_MULTI_INVERT)
  693. #if 0
  694. FLOAT Counter_Timer100Ns_Multi_Inv(PLINESTRUCT pLineStruct)
  695. {
  696.         return Counter_Timer_Common(pLineStruct, NS100_MULTI_INVERT) ;
  697. }
  698. #endif
  699.  
  700. /*****************************************************************************
  701.  * Counter_Timer - Take the difference between the current and previous
  702.  *                 counts,
  703.  *                 Normalize the count (counts per interval)
  704.  *                 divide by the time interval (count = % of interval)
  705.  *                 multiply by 100 (convert to a percentage)
  706.  *                 this value from 100.
  707.  ****************************************************************************/
  708. #define Counter_Timer(pLineStruct)       \
  709.         Counter_Timer_Common(pLineStruct, 0)
  710. #if 0
  711. FLOAT Counter_Timer(PLINESTRUCT pLineStruct)
  712. {
  713.         return Counter_Timer_Common(pLineStruct, 0) ;
  714. }
  715. #endif
  716.  
  717.  
  718. /*****************************************************************************
  719.  * Counter_Timer_Inv - Take the difference between the current and previous
  720.  *                     counts,
  721.  *                     Normalize the count (counts per interval)
  722.  *                     divide by the time interval (count = % of interval)
  723.  *                     subtract from 1 (the normalized size of an interval)
  724.  *                     multiply by 100 (convert to a percentage)
  725.  *                     this value from 100.
  726.  ****************************************************************************/
  727. #define Counter_Timer_Inv(pLineStruct)         \
  728.       Counter_Timer_Common(pLineStruct, INVERT)
  729. #if 0
  730. FLOAT Counter_Timer_Inv(PLINESTRUCT pLineStruct)
  731. {
  732.         return Counter_Timer_Common(pLineStruct, INVERT) ;
  733. }
  734. #endif
  735.  
  736. /*****************************************************************************
  737.  * Sample_Counter -
  738.  ****************************************************************************/
  739. #define Sample_Counter(pLineStruct)      \
  740.       Sample_Common(pLineStruct, 0)
  741. #if 0
  742. FLOAT Sample_Counter(PLINESTRUCT pLineStruct)
  743. {
  744.         return Sample_Common(pLineStruct, 0) ;
  745. }
  746. #endif
  747.  
  748. /*****************************************************************************
  749.  * Sample_Fraction -
  750.  ****************************************************************************/
  751. #define Sample_Fraction(pLineStruct)     \
  752.      Sample_Common(pLineStruct, FRACTION)
  753. #if 0
  754. FLOAT Sample_Fraction(PLINESTRUCT pLineStruct)
  755. {
  756.         return Sample_Common(pLineStruct, FRACTION) ;
  757. }
  758. #endif
  759.  
  760. /*****************************************************************************
  761.  * Counter_Rawcount - This is just a raw count.
  762.  ****************************************************************************/
  763. #define Counter_Rawcount(pLineStruct)     \
  764.    ((FLOAT) ((DWORD) (pLineStruct->lnaCounterValue[0])))
  765. #if 0
  766. FLOAT Counter_Rawcount(PLINESTRUCT pLineStruct)
  767.    {
  768.    return((FLOAT) (pLineStruct->lnaCounterValue[0])) ;
  769.    }
  770. #endif
  771.  
  772. /*****************************************************************************
  773.  * Counter_Large_Rawcount - This is just a raw count.
  774.  ****************************************************************************/
  775. #define Counter_Large_Rawcount(pLineStruct)     \
  776.    ((FLOAT) (pLineStruct->lnaCounterValue[0]))
  777.  
  778. /*****************************************************************************
  779.  * Counter_Elapsed_Time -
  780.  ****************************************************************************/
  781. #define Counter_Elapsed_Time(pLineStruct)         \
  782.     eElapsedTime (pLineStruct, 0)
  783. #if 0
  784. FLOAT Counter_Elapsed_Time (PLINESTRUCT pLineStruct)
  785. {
  786.     return eElapsedTime (pLineStruct, 0);
  787. }
  788. #endif
  789.  
  790. /*****************************************************************************
  791.  * Counter_Null - The counters that return nothing go here.
  792.  ****************************************************************************/
  793. #define Counter_Null(pline)        \
  794.         ((FLOAT) 0.0)
  795. #if 0
  796. FLOAT Counter_Null(PLINESTRUCT pline)
  797. {
  798.         return((FLOAT) 0.0);
  799.         pline;
  800. }
  801. #endif
  802.  
  803.  
  804. FLOAT
  805. CounterEntry (
  806.     PLINESTRUCT pLine
  807. )
  808. {
  809.     switch (pLine->lnCounterType) {
  810.         case  PERF_COUNTER_COUNTER:
  811.             return Counter_Counter (pLine);
  812.  
  813.         case  PERF_COUNTER_TIMER:
  814.             return Counter_Timer (pLine);
  815.  
  816.         case  PERF_COUNTER_QUEUELEN_TYPE:
  817.             return Counter_Queuelen(pLine);
  818.  
  819.         case  PERF_COUNTER_BULK_COUNT:
  820.             return Counter_Bulk (pLine);
  821.  
  822.         case  PERF_COUNTER_TEXT:
  823.             return Counter_Null (pLine);
  824.  
  825.         case  PERF_COUNTER_RAWCOUNT:
  826.         case  PERF_COUNTER_RAWCOUNT_HEX:
  827.             return Counter_Rawcount(pLine);
  828.  
  829.         case  PERF_COUNTER_LARGE_RAWCOUNT:
  830.         case  PERF_COUNTER_LARGE_RAWCOUNT_HEX:
  831.             return Counter_Large_Rawcount(pLine);
  832.  
  833.         case  PERF_SAMPLE_FRACTION:
  834.             return Sample_Fraction(pLine);
  835.  
  836.         case  PERF_SAMPLE_COUNTER:
  837.             return Sample_Counter (pLine);
  838.  
  839.         case  PERF_COUNTER_NODATA:
  840.             return Counter_Null (pLine);
  841.  
  842.         case  PERF_COUNTER_TIMER_INV:
  843.             return Counter_Timer_Inv (pLine);
  844.  
  845.         case  PERF_RAW_BASE:
  846. //      case  PERF_SAMPLE_BASE:
  847. //      case  PERF_AVERAGE_BASE:
  848.             return Counter_Null (pLine);
  849.  
  850.         case  PERF_AVERAGE_TIMER:
  851.             return Counter_Average_Timer (pLine);
  852.  
  853.         case  PERF_AVERAGE_BULK:
  854.             return Counter_Average_Bulk (pLine);
  855.  
  856.         case  PERF_100NSEC_TIMER:
  857.             return Counter_Timer100Ns (pLine);
  858.  
  859.         case  PERF_100NSEC_TIMER_INV:
  860.             return Counter_Timer100Ns_Inv (pLine);
  861.  
  862.         case  PERF_COUNTER_MULTI_TIMER:
  863.             return Counter_Timer_Multi (pLine);
  864.  
  865.         case  PERF_COUNTER_MULTI_TIMER_INV:
  866.             return Counter_Timer_Multi_Inv (pLine);
  867.  
  868.         case  PERF_COUNTER_MULTI_BASE:
  869.             return Counter_Null (pLine);
  870.  
  871.         case  PERF_100NSEC_MULTI_TIMER:
  872.             return Counter_Timer100Ns_Multi (pLine);
  873.                  
  874.         case  PERF_100NSEC_MULTI_TIMER_INV:
  875.             return Counter_Timer100Ns_Multi_Inv (pLine);
  876.  
  877.         case  PERF_RAW_FRACTION:
  878.             return Counter_Raw_Fraction (pLine);
  879.  
  880.         case  PERF_ELAPSED_TIME:
  881.             return Counter_Elapsed_Time (pLine);
  882.            
  883.         default:
  884.             return Counter_Null (pLine);
  885.  
  886.     }
  887. }
  888.  
  889.  
  890. BOOL
  891. IsCounterSupported (
  892.     DWORD dwCounterType
  893. )
  894. {
  895.     switch (dwCounterType) {
  896. // supported counters
  897.         case  PERF_COUNTER_COUNTER:
  898.         case  PERF_COUNTER_TIMER:
  899.         case  PERF_COUNTER_QUEUELEN_TYPE:
  900.         case  PERF_COUNTER_BULK_COUNT:
  901.         case  PERF_COUNTER_RAWCOUNT:
  902.         case  PERF_COUNTER_RAWCOUNT_HEX:
  903.         case  PERF_COUNTER_LARGE_RAWCOUNT:
  904.         case  PERF_COUNTER_LARGE_RAWCOUNT_HEX:
  905.         case  PERF_SAMPLE_FRACTION:
  906.         case  PERF_SAMPLE_COUNTER:
  907.         case  PERF_COUNTER_TIMER_INV:
  908.         case  PERF_AVERAGE_TIMER:
  909.         case  PERF_AVERAGE_BULK:
  910.         case  PERF_100NSEC_TIMER:
  911.         case  PERF_100NSEC_TIMER_INV:
  912.         case  PERF_COUNTER_MULTI_TIMER:
  913.         case  PERF_COUNTER_MULTI_TIMER_INV:
  914.         case  PERF_100NSEC_MULTI_TIMER:
  915.         case  PERF_100NSEC_MULTI_TIMER_INV:
  916.         case  PERF_RAW_FRACTION:
  917.         case  PERF_ELAPSED_TIME:
  918.             return TRUE;
  919.  
  920. // unsupported counters
  921.         case  PERF_COUNTER_TEXT:
  922.         case  PERF_COUNTER_NODATA:
  923.         case  PERF_RAW_BASE:
  924. //      case  PERF_SAMPLE_BASE:
  925. //      case  PERF_AVERAGE_BASE:
  926.         case  PERF_COUNTER_MULTI_BASE:
  927.         default:
  928.             return FALSE;
  929.  
  930.     }
  931. }
  932.