Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

952 lines
27 KiB

  1. /*++
  2. Copyright (C) 1995-2001 Microsoft Corporation
  3. Module Name:
  4. COUNTERS.CPP
  5. Abstract:
  6. Has the routines needed to message the counter data. Note that
  7. this code was almost completly pilfered from the perfmon sample
  8. code done by Robert Watson and this ensures that the answers
  9. match what perfmon would give.
  10. History:
  11. a-davj 12-20-95 v0.01.
  12. --*/
  13. #include "precomp.h"
  14. #include <winperf.h>
  15. #include "perfcach.h" // Exported declarations for this file
  16. #define INVERT PERF_COUNTER_TIMER_INV
  17. #define NS100_INVERT PERF_100NSEC_TIMER_INV
  18. #define NS100 PERF_100NSEC_TIMER
  19. #define TIMER_MULTI PERF_COUNTER_MULTI_TIMER
  20. #define TIMER_MULTI_INVERT PERF_COUNTER_MULTI_TIMER_INV
  21. #define NS100_MULTI PERF_100NSEC_MULTI_TIMER
  22. #define NS100_MULTI_INVERT PERF_100NSEC_MULTI_TIMER_INV
  23. #define FRACTION 1
  24. #define BULK 1
  25. #define TOO_BIG (FLOAT)1500000000
  26. #pragma optimize("", off)
  27. //***************************************************************************
  28. // FLOAT eGetTimeInterval
  29. //
  30. // DESCRIPTION:
  31. //
  32. // Get the difference between the current and previous time counts,
  33. // then divide by the frequency.
  34. //
  35. // PARAMETERS:
  36. //
  37. // pCurrentTime current time in ticks.
  38. // pPreviousTime previous time in ticks.
  39. // pliFreq # of counts (clock ticks) per second
  40. //
  41. // RETURN VALUE:
  42. //
  43. // Floating point representation of Time Interval (seconds), 0.0 if error
  44. //***************************************************************************
  45. FLOAT eGetTimeInterval(
  46. IN LONGLONG *pliCurrentTime,
  47. IN LONGLONG *pliPreviousTime,
  48. IN LONGLONG *pliFreq)
  49. {
  50. FLOAT eTimeDifference;
  51. FLOAT eFreq;
  52. FLOAT eTimeInterval ;
  53. LONGLONG liDifference;
  54. // Get the number of counts that have occured since the last sample
  55. liDifference = *pliCurrentTime - *pliPreviousTime;
  56. if (liDifference <= (LONGLONG)0)
  57. {
  58. return (FLOAT) 0.0f;
  59. }
  60. else
  61. {
  62. eTimeDifference = (FLOAT)liDifference;
  63. // Get the counts per second
  64. eFreq = (FLOAT)(*pliFreq) ;
  65. if (eFreq <= 0.0f)
  66. return (FLOAT) 0.0f;
  67. // Get the time since the last sample.
  68. eTimeInterval = eTimeDifference / eFreq ;
  69. return (eTimeInterval) ;
  70. }
  71. } // eGetTimeInterval
  72. //***************************************************************************
  73. // FLOAT Counter_Counter_Common
  74. //
  75. // DESCRIPTION:
  76. //
  77. // Take the difference between the current and previous counts
  78. // then divide by the time interval
  79. //
  80. // PARAMETERS:
  81. //
  82. // pLineStruct Line structure containing data to perform computations on
  83. //
  84. // iType Counter Type
  85. //
  86. //
  87. // RETURN VALUE:
  88. //
  89. // Floating point representation of outcome, 0.0 if error
  90. //***************************************************************************
  91. FLOAT Counter_Counter_Common(
  92. IN PLINESTRUCT pLineStruct,
  93. IN INT iType)
  94. {
  95. FLOAT eTimeInterval;
  96. FLOAT eDifference;
  97. FLOAT eCount ;
  98. BOOL bValueDrop = FALSE ;
  99. LONGLONG liDifference;
  100. if (iType != BULK)
  101. {
  102. // check if it is too big to be a wrap-around case
  103. if (pLineStruct->lnaCounterValue[0] <
  104. pLineStruct->lnaOldCounterValue[0])
  105. {
  106. if (pLineStruct->lnaCounterValue[0] -
  107. pLineStruct->lnaOldCounterValue[0] > (DWORD)0x00ffff0000)
  108. {
  109. return (FLOAT) 0.0f;
  110. }
  111. bValueDrop = TRUE ;
  112. }
  113. liDifference = pLineStruct->lnaCounterValue[0] -
  114. pLineStruct->lnaOldCounterValue[0];
  115. liDifference &= (DWORD)(0x0ffffffff);
  116. }
  117. else
  118. {
  119. liDifference = pLineStruct->lnaCounterValue[0] -
  120. pLineStruct->lnaOldCounterValue[0];
  121. }
  122. if (liDifference <= (LONGLONG) 0)
  123. {
  124. return (FLOAT) 0.0f;
  125. }
  126. else
  127. {
  128. eTimeInterval = eGetTimeInterval(&pLineStruct->lnNewTime,
  129. &pLineStruct->lnOldTime,
  130. &pLineStruct->lnPerfFreq) ;
  131. if (eTimeInterval <= 0.0f)
  132. {
  133. return (FLOAT) 0.0f;
  134. }
  135. else
  136. {
  137. eDifference = (FLOAT)(liDifference);
  138. eCount = eDifference / eTimeInterval ;
  139. if (bValueDrop && eCount > (FLOAT) TOO_BIG)
  140. {
  141. // ignore this bogus data since it is too big for
  142. // the wrap-around case
  143. eCount = (FLOAT) 0.0f ;
  144. }
  145. return(eCount) ;
  146. }
  147. }
  148. } // Counter_Counter_Common
  149. //***************************************************************************
  150. // FLOAT Counter_Queuelen
  151. //
  152. // DESCRIPTION:
  153. //
  154. // Calculates queue lengths.
  155. //
  156. // PARAMETERS:
  157. //
  158. // pLineStruct Line structure containing data to perform computations on
  159. //
  160. // bLarge TRUE if type LARGE
  161. //
  162. //
  163. // RETURN VALUE:
  164. //
  165. // Floating point representation of outcome, 0.0 if error
  166. //***************************************************************************
  167. FLOAT Counter_Queuelen(IN PLINESTRUCT pLineStruct, IN BOOL bLarge, IN BOOL b100NS)
  168. {
  169. FLOAT eTimeInterval;
  170. FLOAT eDifference;
  171. FLOAT eCount ;
  172. BOOL bValueDrop = FALSE ;
  173. LONGLONG liDifference;
  174. if (!bLarge)
  175. {
  176. // check if it is too big to be a wrap-around case
  177. if (pLineStruct->lnaCounterValue[0] <
  178. pLineStruct->lnaOldCounterValue[0])
  179. {
  180. if (pLineStruct->lnaCounterValue[0] -
  181. pLineStruct->lnaOldCounterValue[0] > (DWORD)0x00ffff0000)
  182. {
  183. return (FLOAT) 0.0f;
  184. }
  185. bValueDrop = TRUE ;
  186. }
  187. liDifference = pLineStruct->lnaCounterValue[0] -
  188. pLineStruct->lnaOldCounterValue[0];
  189. liDifference &= (DWORD)(0x0ffffffff);
  190. }
  191. else
  192. {
  193. liDifference = pLineStruct->lnaCounterValue[0] -
  194. pLineStruct->lnaOldCounterValue[0];
  195. }
  196. if (liDifference <= (LONGLONG) 0)
  197. {
  198. return (FLOAT) 0.0f;
  199. }
  200. eDifference = (float)liDifference;
  201. if(b100NS)
  202. eTimeInterval = pLineStruct->lnNewTime100Ns - pLineStruct->lnOldTime100Ns;
  203. else
  204. eTimeInterval = pLineStruct->lnNewTime - pLineStruct->lnOldTime;
  205. if (eTimeInterval <= 0.0f)
  206. {
  207. return (FLOAT) 0.0f;
  208. }
  209. eCount = eDifference / eTimeInterval ;
  210. return(eCount) ;
  211. }
  212. //***************************************************************************
  213. // FLOAT Counter_Average_Timer
  214. //
  215. // DESCRIPTION:
  216. //
  217. // Take the differences between the current and previous times and counts
  218. // divide the time interval by the counts multiply by 10,000,000 (convert
  219. // from 100 nsec to sec)
  220. //
  221. // PARAMETERS:
  222. //
  223. // pLineStruct Line structure containing data to perform computations on
  224. //
  225. // RETURN VALUE:
  226. //
  227. // Floating point representation of outcome, 0.0 if error
  228. //***************************************************************************
  229. FLOAT Counter_Average_Timer(
  230. IN PLINESTRUCT pLineStruct)
  231. {
  232. FLOAT eTimeInterval;
  233. FLOAT eCount;
  234. LONGLONG liDifference;
  235. // Get the current and previous counts.
  236. liDifference = (DWORD)pLineStruct->lnaCounterValue[1] -
  237. (DWORD)pLineStruct->lnaOldCounterValue[1];
  238. if ( liDifference <= 0)
  239. {
  240. return (FLOAT) 0.0f;
  241. }
  242. else
  243. {
  244. // Get the amount of time that has passed since the last sample
  245. eTimeInterval = eGetTimeInterval(&pLineStruct->lnaCounterValue[0],
  246. &pLineStruct->lnaOldCounterValue[0],
  247. &pLineStruct->lnPerfFreq) ;
  248. if (eTimeInterval < 0.0f)
  249. { // return 0 if negative time has passed
  250. return (0.0f);
  251. }
  252. else
  253. {
  254. // Get the number of counts in this time interval.
  255. eCount = eTimeInterval / ((FLOAT)liDifference);
  256. return(eCount) ;
  257. }
  258. }
  259. } //Counter_Average_Timer
  260. //***************************************************************************
  261. // FLOAT Counter_Average_Bulk
  262. //
  263. // DESCRIPTION:
  264. //
  265. // Take the differences between the current and previous byte counts and
  266. // operation counts divide the bulk count by the operation counts
  267. //
  268. // PARAMETERS:
  269. //
  270. // pLineStruct Line structure containing data to perform computations on
  271. //
  272. // RETURN VALUE:
  273. //
  274. // Floating point representation of outcome, 0.0 if error
  275. //***************************************************************************
  276. FLOAT Counter_Average_Bulk(
  277. IN PLINESTRUCT pLineStruct)
  278. {
  279. FLOAT eBulkDelta;
  280. FLOAT eDifference;
  281. FLOAT eCount;
  282. LONGLONG liDifference;
  283. LONGLONG liBulkDelta;
  284. // Get the bulk count increment since the last sample
  285. liBulkDelta = pLineStruct->lnaCounterValue[0] -
  286. pLineStruct->lnaOldCounterValue[0];
  287. if (liBulkDelta <= (LONGLONG) 0)
  288. {
  289. return (FLOAT) 0.0f;
  290. }
  291. else
  292. {
  293. // Get the current and previous counts.
  294. liDifference = (DWORD)pLineStruct->lnaCounterValue[1] -
  295. (DWORD) pLineStruct->lnaOldCounterValue[1];
  296. liDifference &= (DWORD) (0x0ffffffff);
  297. // Get the number of counts in this time interval.
  298. if ( liDifference <= (LONGLONG) 0)
  299. {
  300. // Counter value invalid
  301. return (FLOAT) 0.0f;
  302. }
  303. else
  304. {
  305. eBulkDelta = (FLOAT) (liBulkDelta);
  306. eDifference = (FLOAT) (liDifference);
  307. eCount = eBulkDelta / eDifference ;
  308. // Scale the value to up to 1 second
  309. return(eCount) ;
  310. }
  311. }
  312. } // Counter_Average_Bulk
  313. //***************************************************************************
  314. // FLOAT Counter_Timer_Common
  315. //
  316. // DESCRIPTION:
  317. //
  318. // Take the difference between the current and previous counts,
  319. // Normalize the count (counts per interval)
  320. // divide by the time interval (count = % of interval)
  321. // if (invert)
  322. // subtract from 1 (the normalized size of an interval)
  323. // multiply by 100 (convert to a percentage)
  324. // this value from 100.
  325. //
  326. // PARAMETERS:
  327. //
  328. // pLineStruct Line structure containing data to perform computations on
  329. // iType Counter Type
  330. //
  331. // RETURN VALUE:
  332. // Floating point representation of outcome, 0.0 if error
  333. //***************************************************************************
  334. FLOAT Counter_Timer_Common(
  335. IN PLINESTRUCT pLineStruct,
  336. IN INT iType)
  337. {
  338. FLOAT eTimeInterval;
  339. FLOAT eDifference;
  340. FLOAT eFreq;
  341. FLOAT eFraction;
  342. FLOAT eMultiBase;
  343. FLOAT eCount ;
  344. LONGLONG liTimeInterval;
  345. LONGLONG liDifference;
  346. // Get the amount of time that has passed since the last sample
  347. if (iType == NS100 ||
  348. iType == NS100_INVERT ||
  349. iType == NS100_MULTI ||
  350. iType == NS100_MULTI_INVERT)
  351. {
  352. liTimeInterval = pLineStruct->lnNewTime100Ns -
  353. pLineStruct->lnOldTime100Ns ;
  354. eTimeInterval = (FLOAT) (liTimeInterval);
  355. }
  356. else
  357. {
  358. eTimeInterval = eGetTimeInterval(&pLineStruct->lnNewTime,
  359. &pLineStruct->lnOldTime,
  360. &pLineStruct->lnPerfFreq) ;
  361. }
  362. if (eTimeInterval <= 0.0f)
  363. return (FLOAT) 0.0f;
  364. // Get the current and previous counts.
  365. liDifference = pLineStruct->lnaCounterValue[0] -
  366. pLineStruct->lnaOldCounterValue[0] ;
  367. // Get the number of counts in this time interval.
  368. // (1, 2, 3 or any number of seconds could have gone by since
  369. // the last sample)
  370. eDifference = (FLOAT) (liDifference) ;
  371. if (iType == 0 || iType == INVERT)
  372. {
  373. // Get the counts per interval (second)
  374. eFreq = (FLOAT) (pLineStruct->lnPerfFreq) ;
  375. if (eFreq <= 0.0f)
  376. return (FLOAT) 0.0f;
  377. // Calculate the fraction of the counts that are used by whatever
  378. // we are measuring
  379. eFraction = eDifference / eFreq ;
  380. }
  381. else
  382. {
  383. eFraction = eDifference ;
  384. }
  385. // Calculate the fraction of time used by what were measuring.
  386. eCount = eFraction / eTimeInterval ;
  387. // If this is an inverted count take care of the inversion.
  388. if (iType == INVERT || iType == NS100_INVERT)
  389. eCount = (FLOAT) 1.0 - eCount ;
  390. // Do extra calculation for multi timers.
  391. if(iType == TIMER_MULTI || iType == NS100_MULTI ||
  392. iType == TIMER_MULTI_INVERT || iType == NS100_MULTI_INVERT)
  393. {
  394. eMultiBase = (float)pLineStruct->lnaCounterValue[1];
  395. if(eMultiBase == 0.0)
  396. return 0.0f;
  397. if (iType == TIMER_MULTI_INVERT || iType == NS100_MULTI_INVERT)
  398. eCount = eMultiBase - eCount;
  399. eCount /= eMultiBase;
  400. }
  401. // Scale the value to up to 100.
  402. eCount *= 100.0f ;
  403. if (eCount < 0.0f) eCount = 0.0f ;
  404. if (eCount > 100.0f &&
  405. iType != NS100_MULTI &&
  406. iType != NS100_MULTI_INVERT &&
  407. iType != TIMER_MULTI &&
  408. iType != TIMER_MULTI_INVERT)
  409. {
  410. eCount = 100.0f;
  411. }
  412. return(eCount) ;
  413. } // Counter_Timer_Common
  414. //***************************************************************************
  415. // FLOAT Counter_Raw_Fraction
  416. //
  417. // DESCRIPTION:
  418. //
  419. // Evaluate a raw fraction (no time, just two values: Numerator and
  420. // Denominator) and multiply by 100 (to make a percentage;
  421. //
  422. // PARAMETERS:
  423. //
  424. // pLineStruct Line structure containing data to perform computations on
  425. //
  426. // RETURN VALUE:
  427. // Floating point representation of outcome, 0.0 if error
  428. //***************************************************************************
  429. FLOAT Counter_Raw_Fraction(
  430. IN PLINESTRUCT pLineStruct)
  431. {
  432. FLOAT eCount ;
  433. LONGLONG liNumerator;
  434. if ( pLineStruct->lnaCounterValue[0] == 0 ||
  435. pLineStruct->lnaCounterValue[1] == 0 )
  436. {
  437. // invalid value
  438. return (0.0f);
  439. }
  440. else
  441. {
  442. liNumerator = pLineStruct->lnaCounterValue[0] * 100;
  443. eCount = ((FLOAT) (liNumerator)) /
  444. ((FLOAT) pLineStruct->lnaCounterValue[1]);
  445. return(eCount) ;
  446. }
  447. } // Counter_Raw_Fraction
  448. //***************************************************************************
  449. // FLOAT eElapsedTime
  450. //
  451. // DESCRIPTION:
  452. //
  453. // Converts 100NS elapsed time to fractional seconds
  454. //
  455. // PARAMETERS:
  456. //
  457. // pLineStruct Line structure containing data to perform computations on
  458. // iType Unused.
  459. //
  460. // RETURN VALUE:
  461. //
  462. // Floating point representation of elapsed time in seconds, 0.0 if error
  463. //***************************************************************************
  464. FLOAT eElapsedTime(
  465. IN PLINESTRUCT pLineStruct,
  466. IN INT iType)
  467. {
  468. FLOAT eSeconds ;
  469. LONGLONG liDifference;
  470. if (pLineStruct->lnaCounterValue[0] <= (LONGLONG) 0)
  471. {
  472. // no data [start time = 0] so return 0
  473. return (FLOAT) 0.0f;
  474. }
  475. else
  476. {
  477. LONGLONG PerfFreq;
  478. PerfFreq = *(LONGLONG UNALIGNED *)(&pLineStruct->ObjPerfFreq) ;
  479. // otherwise compute difference between current time and start time
  480. liDifference =
  481. pLineStruct->ObjCounterTimeNew - pLineStruct->lnaCounterValue[0];
  482. if (liDifference <= (LONGLONG) 0 ||
  483. PerfFreq <= 0)
  484. {
  485. return (FLOAT) 0.0f;
  486. }
  487. else
  488. {
  489. // convert to fractional seconds using object counter
  490. eSeconds = ((FLOAT) (liDifference)) /
  491. ((FLOAT) (PerfFreq));
  492. return (eSeconds);
  493. }
  494. }
  495. } // eElapsedTime
  496. //***************************************************************************
  497. // FLOAT Sample_Common
  498. //
  499. // DESCRIPTION:
  500. //
  501. // Divides "Top" differenced by Base Difference
  502. //
  503. // PARAMETERS:
  504. //
  505. // pLineStruct Line structure containing data to perform computations on
  506. // iType Counter Type
  507. //
  508. // RETURN VALUE:
  509. //
  510. // Floating point representation of outcome, 0.0 if error
  511. //***************************************************************************
  512. FLOAT Sample_Common(
  513. IN PLINESTRUCT pLineStruct,
  514. IN INT iType)
  515. {
  516. FLOAT eCount ;
  517. LONG lDifference;
  518. LONG lBaseDifference;
  519. lDifference = (DWORD)pLineStruct->lnaCounterValue[0] -
  520. (DWORD)pLineStruct->lnaOldCounterValue[0] ;
  521. lDifference &= (DWORD) (0x0ffffffff);
  522. if (lDifference <= 0)
  523. {
  524. return (FLOAT) 0.0f;
  525. }
  526. else
  527. {
  528. lBaseDifference = (DWORD)pLineStruct->lnaCounterValue[1] -
  529. (DWORD)pLineStruct->lnaOldCounterValue[1] ;
  530. if ( lBaseDifference <= 0 )
  531. {
  532. // invalid value
  533. return (0.0f);
  534. }
  535. else
  536. {
  537. eCount = ((FLOAT)lDifference) / ((FLOAT)lBaseDifference) ;
  538. if (iType == FRACTION)
  539. {
  540. eCount *= (FLOAT) 100.0f ;
  541. }
  542. return(eCount) ;
  543. }
  544. }
  545. } // Sample_Common
  546. //***************************************************************************
  547. //
  548. // FLOAT Counter_Delta
  549. //
  550. // DESCRIPTION:
  551. //
  552. // Take the difference between the current and previous counts,
  553. // PARAMETERS:
  554. //
  555. // pLineStruct Line structure containing data to perform computations on
  556. // bLargeData true if data is large
  557. //
  558. // RETURN VALUE:
  559. //
  560. // Floating point representation of outcome, 0.0 if error
  561. //***************************************************************************
  562. FLOAT Counter_Delta(PLINESTRUCT pLineStruct, BOOL bLargeData)
  563. {
  564. FLOAT eDifference;
  565. LONGLONG llDifference;
  566. ULONGLONG ullThisValue, ullPrevValue;
  567. // Get the current and previous counts.
  568. if (!bLargeData) {
  569. // then clear the high part of the word
  570. ullThisValue = (ULONGLONG)pLineStruct->lnaCounterValue[0];
  571. ullPrevValue = (ULONGLONG)pLineStruct->lnaOldCounterValue[0];
  572. } else {
  573. ullThisValue = (ULONGLONG)pLineStruct->lnaCounterValue[0];
  574. ullPrevValue = (ULONGLONG)pLineStruct->lnaOldCounterValue[0];
  575. }
  576. if (ullThisValue > ullPrevValue) {
  577. llDifference = (LONGLONG)(ullThisValue - ullPrevValue);
  578. eDifference = (FLOAT)llDifference;
  579. } else {
  580. // the new value is smaller than or equal to the old value
  581. // and negative numbers are not allowed.
  582. eDifference = 0.0f;
  583. }
  584. return(eDifference) ;
  585. }
  586. //***************************************************************************
  587. // FLOAT GenericConv
  588. //
  589. // DESCRIPTION:
  590. //
  591. // This handles the data types which the perf monitor doesnt currently
  592. // handle and does so by simply using the "formulas" indicated by the
  593. // bit fields in the counter's type.
  594. //
  595. // PARAMETERS:
  596. //
  597. // pLine Line structure containing data to perform computations on
  598. //
  599. // RETURN VALUE:
  600. //
  601. // Floating point representation of outcome
  602. //***************************************************************************
  603. FLOAT GenericConv(
  604. IN PLINESTRUCT pLine)
  605. {
  606. FLOAT fRet = 0.0f; // default if nothing makes sense
  607. // extract the various bit fields as defined in winperf.h
  608. DWORD PerfType = pLine->lnCounterType & 0x00000c00;
  609. DWORD SubType = pLine->lnCounterType & 0x000f0000;
  610. DWORD CalcMod = pLine->lnCounterType & 0x0fc00000;
  611. DWORD TimerType=pLine->lnCounterType & 0x00300000;
  612. DWORD Display = pLine->lnCounterType & 0xf0000000;
  613. DWORD dwSize = pLine->lnCounterType & 0x00000300;
  614. if(PerfType == PERF_TYPE_NUMBER)
  615. {
  616. // For simple number the calculation is fairly simple and only
  617. // involves a possible division by 1000
  618. fRet = (FLOAT)pLine->lnaCounterValue[0];
  619. if(SubType == PERF_NUMBER_DEC_1000)
  620. fRet /= 1000.0f;
  621. }
  622. else if(PerfType == PERF_TYPE_COUNTER)
  623. {
  624. FLOAT eTimeDelta;
  625. FLOAT eDataDelta;
  626. FLOAT eBaseDelta;
  627. if(SubType == PERF_COUNTER_RATE || SubType ==PERF_COUNTER_QUEUELEN)
  628. {
  629. // Need the delta time. The data used for time delta is
  630. // indicated by a subfield.
  631. if(TimerType == PERF_TIMER_TICK)
  632. eTimeDelta = (((float)pLine->lnNewTime) - pLine->lnOldTime)/
  633. ((float)pLine->lnPerfFreq);
  634. else if(TimerType == PERF_TIMER_100NS)
  635. eTimeDelta = ((float)pLine->lnNewTime100Ns) - pLine->lnOldTime100Ns;
  636. else
  637. eTimeDelta = ((float)pLine->ObjCounterTimeNew -
  638. pLine->ObjCounterTimeOld) / ((float)pLine->ObjPerfFreq);
  639. if(eTimeDelta == 0.0f) // shouldnt happen, but delta can end
  640. return 0.0f; // up as a denominator.
  641. }
  642. if(SubType == PERF_COUNTER_FRACTION)
  643. {
  644. // The base value is going to be used as the denominator.
  645. if(CalcMod & PERF_DELTA_BASE)
  646. eBaseDelta = (float)pLine->lnaCounterValue[1] -
  647. pLine->lnaOldCounterValue[1];
  648. else
  649. eBaseDelta = (float)pLine->lnaCounterValue[1];
  650. if(eBaseDelta == 0.0f) // shouldnt happen, but delta can end
  651. return 0.0f; // up as a denominator.
  652. }
  653. // Get the deta data value.
  654. if(CalcMod & PERF_DELTA_COUNTER)
  655. eDataDelta = (FLOAT)(pLine->lnaCounterValue[0] -
  656. pLine->lnaOldCounterValue[0]);
  657. else
  658. eDataDelta = (FLOAT)pLine->lnaCounterValue[0];
  659. // Apply the appropriate formula
  660. switch(SubType)
  661. {
  662. case PERF_COUNTER_VALUE:
  663. fRet = eDataDelta;
  664. break;
  665. case PERF_COUNTER_RATE:
  666. fRet = eDataDelta / eTimeDelta;
  667. break;
  668. case PERF_COUNTER_FRACTION:
  669. fRet = ((FLOAT)eDataDelta)/eBaseDelta;
  670. break;
  671. case PERF_COUNTER_ELAPSED:
  672. if(TimerType == PERF_OBJECT_TIMER)
  673. fRet = ((float)pLine->ObjCounterTimeNew - pLine->lnaCounterValue[0]) /
  674. ((float)pLine->ObjPerfFreq);
  675. else if(TimerType == PERF_TIMER_TICK)
  676. fRet = ((float)pLine->lnNewTime - pLine->lnaCounterValue[0]) /
  677. ((float)pLine->lnPerfFreq);
  678. else
  679. fRet = (((float)pLine->lnNewTime100Ns) - pLine->lnaCounterValue[0]);
  680. break;
  681. case PERF_COUNTER_QUEUELEN:
  682. fRet = (FLOAT)pLine->lnaCounterValue[0];
  683. fRet = (fRet + (pLine->lnNewTime *pLine->lnaCounterValue[1]))/
  684. eTimeDelta;
  685. break;
  686. default:
  687. fRet = (FLOAT)pLine->lnaCounterValue[0];
  688. }
  689. // Apply the final modifiers for "counters"
  690. if(CalcMod & PERF_INVERSE_COUNTER)
  691. fRet = 1.0f - fRet;
  692. if(Display == PERF_DISPLAY_PERCENT)
  693. fRet *= 100.0f;
  694. }
  695. return fRet;
  696. }
  697. // ***************************************************************************
  698. // FLOAT CounterEntry
  699. //
  700. // DESCRIPTION:
  701. //
  702. // Main routine for converting perf data. In general this routine is
  703. // just a swither for the actual routines that do the conversion.
  704. //
  705. // PARAMETERS:
  706. //
  707. // pLine Line structure containing data to perform computations on
  708. //
  709. // RETURN VALUE:
  710. //
  711. // Floating point representation of outcome, 0.0 if error
  712. // ***************************************************************************
  713. FLOAT CounterEntry (
  714. IN PLINESTRUCT pLine)
  715. {
  716. switch (pLine->lnCounterType)
  717. {
  718. case PERF_COUNTER_COUNTER:
  719. return Counter_Counter_Common(pLine, 0);
  720. case PERF_COUNTER_TIMER:
  721. case PERF_PRECISION_SYSTEM_TIMER:
  722. return Counter_Timer_Common(pLine, 0);
  723. case PERF_COUNTER_BULK_COUNT:
  724. return Counter_Counter_Common(pLine, BULK);
  725. case PERF_COUNTER_TEXT:
  726. return 0.0f;
  727. case PERF_COUNTER_RAWCOUNT:
  728. case PERF_COUNTER_RAWCOUNT_HEX:
  729. return (FLOAT) ((DWORD) (pLine->lnaCounterValue[0]));
  730. case PERF_COUNTER_LARGE_RAWCOUNT:
  731. case PERF_COUNTER_LARGE_RAWCOUNT_HEX:
  732. return (FLOAT) (pLine->lnaCounterValue[0]);
  733. case PERF_SAMPLE_FRACTION:
  734. return Sample_Common(pLine, FRACTION);
  735. case PERF_SAMPLE_COUNTER:
  736. return Sample_Common(pLine, 0);
  737. case PERF_COUNTER_NODATA:
  738. return 0.0f;
  739. case PERF_COUNTER_TIMER_INV:
  740. return Counter_Timer_Common(pLine, INVERT);
  741. case PERF_RAW_BASE:
  742. // case PERF_SAMPLE_BASE:
  743. // case PERF_AVERAGE_BASE:
  744. return 0.0f;
  745. case PERF_AVERAGE_TIMER:
  746. return Counter_Average_Timer(pLine);
  747. case PERF_AVERAGE_BULK:
  748. return Counter_Average_Bulk (pLine);
  749. case PERF_100NSEC_TIMER:
  750. case PERF_PRECISION_100NS_TIMER:
  751. return Counter_Timer_Common(pLine, NS100);
  752. case PERF_100NSEC_TIMER_INV:
  753. return Counter_Timer_Common(pLine, NS100_INVERT);
  754. case PERF_COUNTER_MULTI_TIMER:
  755. return Counter_Timer_Common(pLine, TIMER_MULTI);
  756. case PERF_COUNTER_MULTI_TIMER_INV:
  757. return Counter_Timer_Common(pLine, TIMER_MULTI_INVERT);
  758. case PERF_COUNTER_MULTI_BASE:
  759. return 0.0f;
  760. case PERF_100NSEC_MULTI_TIMER:
  761. return Counter_Timer_Common(pLine, NS100_MULTI);
  762. case PERF_100NSEC_MULTI_TIMER_INV:
  763. return Counter_Timer_Common(pLine, NS100_MULTI_INVERT);
  764. case PERF_COUNTER_LARGE_QUEUELEN_TYPE:
  765. return Counter_Queuelen(pLine, TRUE, FALSE);
  766. case PERF_COUNTER_100NS_QUEUELEN_TYPE:
  767. return Counter_Queuelen(pLine, TRUE, TRUE);
  768. case PERF_COUNTER_QUEUELEN_TYPE:
  769. return Counter_Queuelen(pLine, FALSE, FALSE);
  770. case PERF_RAW_FRACTION:
  771. case PERF_LARGE_RAW_FRACTION:
  772. return Counter_Raw_Fraction (pLine);
  773. case PERF_COUNTER_DELTA:
  774. return Counter_Delta(pLine, FALSE);
  775. case PERF_COUNTER_LARGE_DELTA:
  776. return Counter_Delta(pLine, TRUE);
  777. case PERF_ELAPSED_TIME:
  778. return eElapsedTime (pLine, 0);
  779. default:
  780. return GenericConv (pLine);
  781. }
  782. }