Source code of Windows XP (NT5)
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.

596 lines
16 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1993 - 2000.
  5. //
  6. // File: perfobj.cxx
  7. //
  8. // Contents: Performance Data Object
  9. //
  10. // Classes : CPerfMon, PPerfCounter,
  11. // CPerfCount, CPerfTime,
  12. // CReadUserPerfData
  13. //
  14. // History: 23-March-94 t-joshh Created
  15. //
  16. //----------------------------------------------------------------------------
  17. #include <pch.cxx>
  18. #pragma hdrstop
  19. #include <mutex.hxx>
  20. #include <perfci.hxx>
  21. #include "perfobj2.hxx"
  22. extern CI_DATA_DEFINITION CIDataDefinition;
  23. extern FILTER_DATA_DEFINITION FILTERDataDefinition;
  24. #define FILTERTOTALCOUNTER ((int) FILTERDataDefinition.FILTERObjectType.NumCounters)
  25. #define CITOTALCOUNTER ((int) CIDataDefinition.CIObjectType.NumCounters)
  26. //
  27. // Total size occupied by the counters
  28. //
  29. #define TOTALCOUNTERSIZE ( (FILTERTOTALCOUNTER + CITOTALCOUNTER ) * sizeof(DWORD) )
  30. //+---------------------------------------------------------------------------
  31. //
  32. // Function : CReadUserPerfData::CReadUserPerfData
  33. //
  34. // Purpose : Constructor
  35. //
  36. // Arguments : none
  37. //
  38. // History : 23-March-94 t-joshh Created
  39. //
  40. //----------------------------------------------------------------------------
  41. CReadUserPerfData::CReadUserPerfData() :
  42. _cInstances( 0 ),
  43. _finitOK( FALSE ),
  44. _cCounters( 0 ),
  45. _pSeqNo( 0 ),
  46. _cMaxCats( 0 ),
  47. _cbPerfHeader( 0 )
  48. {
  49. }
  50. //+---------------------------------------------------------------------------
  51. //
  52. // Function : CReadUserPerfData::Finish
  53. //
  54. // Purpose : Close and clean up the handles
  55. //
  56. // Arguments : none
  57. //
  58. // History : 23-March-94 t-joshh Created
  59. //
  60. // Note: Must execute when done with getting the data
  61. //
  62. //----------------------------------------------------------------------------
  63. void CReadUserPerfData::Finish()
  64. {
  65. CleanupForReInit();
  66. _xSharedMemObj.Free();
  67. }
  68. //+---------------------------------------------------------------------------
  69. //
  70. // Member: CReadUserPerfData::CleanupForReInit
  71. //
  72. // Synopsis: Cleans up the data structures in preparation for a
  73. // re-initialization. Only the data which needs to be re-read
  74. // and initialized is thrown away. The Shared memory object is
  75. // NOT deleted because it is system-wide state and there is no
  76. // need to throw it away.
  77. //
  78. // History: 6-21-96 srikants Created
  79. //
  80. //----------------------------------------------------------------------------
  81. void CReadUserPerfData::CleanupForReInit()
  82. {
  83. }
  84. //+---------------------------------------------------------------------------
  85. //
  86. // Function : CReadUserPerfData::InitforRead
  87. //
  88. // Purpose : Initialize to be ready for reading the perf. data
  89. //
  90. // Arguments : none
  91. //
  92. // History : 23-March-94 t-joshh Created
  93. //
  94. // Note: Must be executed before any operations
  95. //
  96. // Return : TRUE -- success, FALSE -- failed
  97. //
  98. //----------------------------------------------------------------------------
  99. BOOL CReadUserPerfData::InitForRead()
  100. {
  101. if ( _xSharedMemObj.IsNull() )
  102. {
  103. ULONG cbCatBitfield, cbSharedMem;
  104. ComputeCIPerfmonVars( _cMaxCats, cbCatBitfield, _cbPerfHeader, cbSharedMem );
  105. //
  106. // Open the shared memory
  107. //
  108. _xSharedMemObj.Set( new CNamedSharedMem() );
  109. BOOL fOK = _xSharedMemObj->OpenForRead( CI_PERF_MEM_NAME );
  110. if ( !fOK )
  111. return FALSE;
  112. _pSeqNo = (UINT *) (((BYTE *)_xSharedMemObj->Get())+sizeof(int) + cbCatBitfield);
  113. }
  114. if ( _finitOK )
  115. CleanupForReInit();
  116. _finitOK = FALSE;
  117. if ( _xSharedMemObj->Ok() )
  118. {
  119. _cInstances = *((int *)_xSharedMemObj->Get());
  120. PerfDebugOut(( DEB_ITRACE, "!!! Reader : No. of Instance : %d\n", _cInstances ));
  121. _cCounters = FILTERTOTALCOUNTER;
  122. _finitOK = TRUE;
  123. return TRUE;
  124. }
  125. return FALSE;
  126. } //InitForRead
  127. //+---------------------------------------------------------------------------
  128. //
  129. // Function : CReadUserPerfData::NumberOfInstance
  130. //
  131. // Purpose : Return the number of existing instances
  132. //
  133. // Arguments : none
  134. //
  135. // History : 23-March-94 t-joshh Created
  136. //
  137. //----------------------------------------------------------------------------
  138. int CReadUserPerfData::NumberOfInstance()
  139. {
  140. return _cInstances;
  141. }
  142. UINT CReadUserPerfData::GetSeqNo() const
  143. {
  144. return _pSeqNo ? *_pSeqNo : 0;
  145. }
  146. //+---------------------------------------------------------------------------
  147. //
  148. // Function : CReadUserPerfData::GetInstanceName
  149. //
  150. // Purpose : Return the specified instance's name
  151. //
  152. // Arguments : [iWhichOne] -- which instance
  153. //
  154. // History : 23-March-94 t-joshh Created
  155. //
  156. //----------------------------------------------------------------------------
  157. WCHAR * CReadUserPerfData::GetInstanceName ( int iWhichOne )
  158. {
  159. if ( !_xSharedMemObj.IsNull() && _xSharedMemObj->Ok() )
  160. {
  161. //
  162. // Find the corresponding slot in the shared memory
  163. //
  164. BYTE * pbBitfield = (BYTE *) _xSharedMemObj->Get() + sizeof(int);
  165. CBitfield bits( pbBitfield );
  166. int i = 0;
  167. for ( int j = 0; j <= iWhichOne && i < (int) _cMaxCats; i++ )
  168. {
  169. if ( bits.IsBitSet( i ) )
  170. j++;
  171. }
  172. iWhichOne = i - 1;
  173. ULONG ByteToSkip = _cbPerfHeader +
  174. ( iWhichOne * cbPerfCatalogSlot ) +
  175. sizeof(int);
  176. return( (WCHAR *)((BYTE *)_xSharedMemObj->Get() + ByteToSkip) );
  177. }
  178. return 0;
  179. } //GetInstanceName
  180. //+---------------------------------------------------------------------------
  181. //
  182. // Function : CReadUserPerfData::GetCounterValue
  183. //
  184. // Purpose : Return the value of the specified counter
  185. //
  186. // Arguments : [iWhichInstance] -- which instance of object does the
  187. // counter belong to
  188. // [iWhichCounter] -- which counter
  189. //
  190. // History : 23-March-94 t-joshh Created
  191. //
  192. //----------------------------------------------------------------------------
  193. DWORD CReadUserPerfData::GetCounterValue( int iWhichInstance, int iWhichCounter )
  194. {
  195. if ( !_xSharedMemObj.IsNull() && _xSharedMemObj->Ok() )
  196. {
  197. //
  198. // Find the corresponding slot
  199. //
  200. BYTE * pbBitfield = (BYTE *) _xSharedMemObj->Get() + sizeof(int);
  201. CBitfield bits( pbBitfield );
  202. int i = 0;
  203. for ( int j = 0; j <= iWhichInstance && i < (int) _cMaxCats; i++ )
  204. {
  205. if ( bits.IsBitSet( i ) )
  206. j++;
  207. }
  208. int iWhichSlot = i - 1;
  209. PerfDebugOut(( DEB_ITRACE, "Choose slot %i\n", iWhichSlot));
  210. ULONG ByteToSkip = _cbPerfHeader
  211. + ( iWhichSlot * cbPerfCatalogSlot )
  212. + sizeof(int)
  213. + ( CI_PERF_MAX_CATALOG_LEN * sizeof(WCHAR) ) // Name of the instance
  214. + ( iWhichCounter * sizeof(DWORD) );
  215. return *(DWORD *)((BYTE *)_xSharedMemObj->Get() + ByteToSkip);
  216. }
  217. return 0;
  218. } //GetCounterValue
  219. //+---------------------------------------------------------------------------
  220. //
  221. // Function : CReadKernelPerfData::CReadKernelPerfData
  222. //
  223. // Purpose : Constructor
  224. //
  225. // Arguments : none
  226. //
  227. // History : 23-March-94 t-joshh Created
  228. //
  229. //----------------------------------------------------------------------------
  230. CReadKernelPerfData::CReadKernelPerfData() :
  231. _pSeqNo(0),
  232. _cInstance( 0 ),
  233. _finitOK( FALSE ),
  234. _cCounters( 0 ),
  235. _cMaxCats( 0 ),
  236. _cbPerfHeader( 0 ),
  237. _cbSharedMem( 0 )
  238. {
  239. }
  240. UINT CReadKernelPerfData::GetSeqNo() const
  241. {
  242. return _pSeqNo ? *_pSeqNo : 0;
  243. }
  244. //+---------------------------------------------------------------------------
  245. //
  246. // Function : CReadKernelPerfData::Finish
  247. //
  248. // Purpose : Close and clean up the handles
  249. //
  250. // Arguments : none
  251. //
  252. // History : 23-March-94 t-joshh Created
  253. //
  254. // Note: Must execute when done with getting the data
  255. //
  256. //----------------------------------------------------------------------------
  257. void CReadKernelPerfData::Finish()
  258. {
  259. CleanupForReInit();
  260. _xSharedMemory.Free();
  261. _xMemory.Free();
  262. _xCatalogs.Free();
  263. _xCatalogMem.Free();
  264. }
  265. //+---------------------------------------------------------------------------
  266. //
  267. // Function : CReadKernelPerfData::FindDownlevelDrives
  268. //
  269. // Purpose : Find the remote drive
  270. //
  271. // History : 23-Mar-94 t-joshh Created
  272. // 31-Jan-96 KyleP Look for all downlevel drives
  273. //
  274. //----------------------------------------------------------------------------
  275. void CReadKernelPerfData::FindDownlevelDrives()
  276. {
  277. if ( _xSharedMemory->Ok() )
  278. {
  279. //
  280. // Get active drive count and active bit array.
  281. //
  282. int cCount = * (int *) _xSharedMemory->Get();
  283. BYTE * pbBitfield = (BYTE *) _xSharedMemory->Get() + sizeof(int);
  284. CBitfield bits( pbBitfield );
  285. //
  286. // Loop through looking for drives.
  287. //
  288. for (int i = 0; cCount > 0 ; cCount--, i++)
  289. {
  290. for (; i < (int) _cMaxCats && !bits.IsBitSet( i ); i++) {}
  291. if ( (int) _cMaxCats == i )
  292. {
  293. PerfDebugOut(( DEB_ITRACE, "!!! Error in the empty slot\n"));
  294. return;
  295. }
  296. else
  297. {
  298. //
  299. // Find offset of drive name in shared memory buffer.
  300. //
  301. ULONG oCounters = _cbPerfHeader +
  302. (i * cbPerfCatalogSlot) +
  303. sizeof(int);
  304. WCHAR * wszTmp = (WCHAR *) ((BYTE *) _xSharedMemory->Get() + oCounters);
  305. //
  306. // Make sure this isn't already in the list
  307. //
  308. for ( int j = 0; j < cCount; j++ )
  309. {
  310. if ( 0 != _xCatalogs[j] && wcscmp( _xCatalogs[j], wszTmp ) == 0 )
  311. break;
  312. }
  313. //
  314. // Add downlevel drive.
  315. //
  316. if ( j == cCount )
  317. {
  318. PerfDebugOut(( DEB_ITRACE, "!!! Kernel Reader : Downlevel Drive %ws\n", wszTmp ));
  319. //
  320. // Find offset of first counter.
  321. //
  322. oCounters += ((sizeof(DWORD) * NUM_KERNEL_AND_USER_COUNTER)
  323. + (CI_PERF_MAX_CATALOG_LEN * sizeof(WCHAR)));
  324. _xCatalogMem[_cInstance] = (void *) ((BYTE *) _xSharedMemory->Get() + oCounters);
  325. _xCatalogs[_cInstance] = new WCHAR[wcslen(wszTmp) + 1];
  326. wcscpy(_xCatalogs[_cInstance++], wszTmp);
  327. }
  328. }
  329. }
  330. }
  331. } //FindDownlevelDrives
  332. //+---------------------------------------------------------------------------
  333. //
  334. // Member: CReadKernelPerfData::CleanupForReInit
  335. //
  336. // Synopsis: Cleans up the state and makes it ready for re-initialization.
  337. //
  338. // History: 6-21-96 srikants Created
  339. //
  340. // Notes:
  341. //
  342. //----------------------------------------------------------------------------
  343. void CReadKernelPerfData::CleanupForReInit()
  344. {
  345. for ( int i = 0; i < _cInstance; i++)
  346. {
  347. delete _xCatalogs[i];
  348. _xCatalogs[i] = 0;
  349. }
  350. _cInstance = 0;
  351. }
  352. //+---------------------------------------------------------------------------
  353. //
  354. // Function : CReadKernelPerfData::InitForRead
  355. //
  356. // Purpose : Initialize to be ready for reading the perf. data
  357. //
  358. // Arguments : none
  359. //
  360. // History : 23-Mar-94 t-joshh Created
  361. // 31-Jan-96 KyleP Improvements for downlevel CI
  362. //
  363. // Note: Must be executed before any operations
  364. //
  365. //----------------------------------------------------------------------------
  366. BOOL CReadKernelPerfData::InitForRead()
  367. {
  368. if ( _xSharedMemory.IsNull() )
  369. {
  370. ULONG cbCatBitfield;
  371. ComputeCIPerfmonVars( _cMaxCats, cbCatBitfield, _cbPerfHeader, _cbSharedMem );
  372. //
  373. // Open the shared memory
  374. //
  375. _xSharedMemory.Set( new CNamedSharedMem() );
  376. BOOL fOK = _xSharedMemory->OpenForRead( CI_PERF_MEM_NAME );
  377. if ( !fOK )
  378. return FALSE;
  379. _pSeqNo = (UINT *) (((BYTE *)_xSharedMemory->Get())+sizeof(int) + cbCatBitfield);
  380. }
  381. //
  382. // Initialize the drive list
  383. //
  384. if ( _finitOK )
  385. CleanupForReInit();
  386. _finitOK = FALSE;
  387. if ( _xCatalogs.IsNull() )
  388. _xCatalogs.Init( _cMaxCats );
  389. if ( _xCatalogMem.IsNull() )
  390. _xCatalogMem.Init( _cMaxCats );
  391. for ( unsigned j = 0; j < _cMaxCats; j++)
  392. {
  393. _xCatalogs[j] = 0;
  394. _xCatalogMem[j] = 0;
  395. }
  396. FindDownlevelDrives();
  397. _cCounters = CITOTALCOUNTER;
  398. _finitOK = TRUE;
  399. return TRUE;
  400. PerfDebugOut(( DEB_ITRACE, "!!! Kernel Reader : Initialize finish\n"));
  401. } //InitForRead
  402. //+---------------------------------------------------------------------------
  403. //
  404. // Function : CReadKernelPerfData::NumberOfInstance
  405. //
  406. // Purpose : Return the number of existing instances
  407. //
  408. // Arguments : none
  409. //
  410. // History : 23-March-94 t-joshh Created
  411. //
  412. //----------------------------------------------------------------------------
  413. int CReadKernelPerfData::NumberOfInstance()
  414. {
  415. return _cInstance;
  416. }
  417. //+---------------------------------------------------------------------------
  418. //
  419. // Function : CReadKernelPerfData::GetInstanceName
  420. //
  421. // Purpose : Return the specified instance's name
  422. //
  423. // Arguments : [iWhichOne] -- which instance
  424. //
  425. // History : 23-March-94 t-joshh Created
  426. //
  427. //----------------------------------------------------------------------------
  428. WCHAR * CReadKernelPerfData::GetInstanceName ( int iWhichOne )
  429. {
  430. return _xCatalogs[iWhichOne];
  431. }
  432. //+---------------------------------------------------------------------------
  433. //
  434. // Function : CReadKernelPerfData::Refresh
  435. //
  436. // Purpose : Retrieve the most updated data
  437. //
  438. // Arguments : [iWhichInstance] -- which instance of object does the
  439. // counter belong to
  440. //
  441. // History : 23-March-94 t-joshh Created
  442. //
  443. //----------------------------------------------------------------------------
  444. BOOL CReadKernelPerfData::Refresh( int iWhichInstance )
  445. {
  446. //
  447. // the instance is either downlevel drive or remote drive
  448. //
  449. Win4Assert( 0 != _cbSharedMem );
  450. if ( _xMemory.IsNull() )
  451. _xMemory.Init( _cbSharedMem );
  452. ULONG oCounters = _cbPerfHeader +
  453. sizeof(int) +
  454. (CI_PERF_MAX_CATALOG_LEN * sizeof WCHAR);
  455. if ( _xCatalogMem.IsNull() )
  456. _xCatalogMem.Init( _cMaxCats );
  457. void * pvTmp = _xCatalogMem[iWhichInstance];
  458. for ( int j = 0; j < CITOTALCOUNTER; j++)
  459. {
  460. *(DWORD *)(_xMemory.GetPointer() + oCounters) = *(DWORD *)pvTmp;
  461. oCounters += sizeof(DWORD);
  462. pvTmp = (void *)((BYTE *)pvTmp + sizeof(DWORD));
  463. }
  464. return TRUE;
  465. } //Refresh
  466. //+---------------------------------------------------------------------------
  467. //
  468. // Function : CReadKernelPerfData::GetCounterValue
  469. //
  470. // Purpose : Return the value of the specified counter
  471. //
  472. // Arguments : [iWhichCounter] -- which counter
  473. //
  474. // History : 23-March-94 t-joshh Created
  475. //
  476. //----------------------------------------------------------------------------
  477. DWORD CReadKernelPerfData::GetCounterValue( int iWhichCounter )
  478. {
  479. if ( !_xMemory.IsNull() )
  480. {
  481. ULONG ByteToSkip = _cbPerfHeader
  482. + sizeof(int)
  483. + (CI_PERF_MAX_CATALOG_LEN * sizeof WCHAR) // Name of the instance
  484. + ( iWhichCounter * sizeof(DWORD) );
  485. return *(DWORD *)(_xMemory.GetPointer() + ByteToSkip);
  486. }
  487. return 0;
  488. } //GetCounterValue