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.

597 lines
15 KiB

  1. // PassportPerfMon.cpp: implementation of the PassportPerfMon class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #define _PassportExport_
  5. #include "PassportExport.h"
  6. #include "PassportPerfMon.h"
  7. #include "PassportPerf.h"
  8. #include <crtdbg.h>
  9. //-------------------------------------------------------------
  10. //
  11. // PassportPerfMon const
  12. //
  13. //-------------------------------------------------------------
  14. PassportPerfMon::PassportPerfMon( ) : PassportSharedMemory()
  15. {
  16. isInited = FALSE;
  17. dwNumInstances = 0;
  18. }
  19. //-------------------------------------------------------------
  20. //
  21. // ~PassportPerfMon
  22. //
  23. //-------------------------------------------------------------
  24. PassportPerfMon::~PassportPerfMon()
  25. {
  26. }
  27. //-------------------------------------------------------------
  28. //
  29. // init
  30. //
  31. //-------------------------------------------------------------
  32. BOOL PassportPerfMon::init( LPCTSTR lpcPerfObjectName )
  33. {
  34. if (isInited)
  35. {
  36. return FALSE;
  37. }
  38. _ASSERT( lpcPerfObjectName );
  39. InitializeCriticalSection(&mInitLock);
  40. EnterCriticalSection(&mInitLock);
  41. // File mapped memory layout
  42. // 1. MAX_COUNTERS of DWORD for the counter types
  43. // 2. if dwNumInstances == 0, then
  44. // (a) MAX_COUNTERS of DWORDS of the counter data
  45. // else (dwNumInstances > 0)
  46. // (b) MAX_COUNTERS of INSTANCE_DATA structures each followed
  47. // immediately by MAX_COUNTERS of DWORDS of the counter data
  48. DWORD dwSize = (
  49. (MAX_COUNTERS * sizeof(DWORD)) // for counter type
  50. + (MAX_INSTANCES *
  51. (sizeof(INSTANCE_DATA) + (MAX_COUNTERS * sizeof(DWORD))))
  52. );
  53. if (!CreateSharedMemory(0, dwSize, lpcPerfObjectName, TRUE))
  54. {
  55. // raise information alert
  56. if (!OpenSharedMemory (lpcPerfObjectName, TRUE ))
  57. {
  58. LeaveCriticalSection(&mInitLock);
  59. return FALSE;
  60. }
  61. }
  62. // zero new memory
  63. memset((void *)m_pbShMem, 0, dwSize);
  64. // setup counter types to default, note that the counters
  65. // start at index 1 in SHM
  66. PPERF_COUNTER_BLOCK pCounterBlock = (PPERF_COUNTER_BLOCK)m_pbShMem;
  67. _ASSERT(pCounterBlock);
  68. for (DWORD i = 0; i < MAX_COUNTERS; i++)
  69. {
  70. PDWORD pdwCounter = ((PDWORD) pCounterBlock) + i;
  71. _ASSERT(pdwCounter);
  72. *pdwCounter = (LONG)PERF_TYPE_ZERO;
  73. }
  74. isInited = TRUE;
  75. LeaveCriticalSection(&mInitLock);
  76. return isInited;
  77. }
  78. //-------------------------------------------------------------
  79. //
  80. // incrementCounter
  81. //
  82. //-------------------------------------------------------------
  83. BOOL PassportPerfMon::incrementCounter ( const DWORD &dwType, LPCSTR lpszInstanceName )
  84. {
  85. if (!isInited)
  86. {
  87. return FALSE;
  88. }
  89. _ASSERT( (dwType >= 0) && (dwType < MAX_COUNTERS));
  90. _ASSERT(m_pbShMem);
  91. DWORD dwIndex = ((dwType == 0) ? 0 : (DWORD)(dwType/2));
  92. BYTE* pb = (BYTE*)m_pbShMem;
  93. _ASSERT(pb);
  94. pb += MAX_COUNTERS * sizeof(DWORD);
  95. // if lpszInstanceName == NULL, select the first datablock after
  96. // the first INSTANCE_DATA, else iterate until we find the
  97. // right instance name
  98. // TBD insert thread locking
  99. for (DWORD i = 0; i < MAX_INSTANCES; i++)
  100. {
  101. INSTANCE_DATA * pInst = (INSTANCE_DATA *)pb;
  102. _ASSERT(pInst);
  103. pb += sizeof(INSTANCE_DATA);
  104. //TODO** mikeguo -- tune up this lookup -- too expensive -- check the first character or something
  105. if (lpszInstanceName == NULL
  106. || (pInst->active && strcmp(pInst->szInstanceName, lpszInstanceName) == 0) )
  107. {
  108. PPERF_COUNTER_BLOCK pCounterBlock = (PPERF_COUNTER_BLOCK)pb;
  109. _ASSERT(pCounterBlock);
  110. PDWORD pdwCounter = ((PDWORD) pCounterBlock) + dwIndex;
  111. _ASSERT(pdwCounter);
  112. InterlockedIncrement((long *)pdwCounter);
  113. return TRUE;
  114. }
  115. pb += (MAX_COUNTERS * sizeof(DWORD));
  116. }
  117. return FALSE;
  118. }
  119. //-------------------------------------------------------------
  120. //
  121. // decrementCounter
  122. //
  123. //-------------------------------------------------------------
  124. BOOL PassportPerfMon::decrementCounter ( const DWORD &dwType, LPCSTR lpszInstanceName )
  125. {
  126. if (!isInited)
  127. {
  128. return FALSE;
  129. }
  130. _ASSERT( (dwType >= 0) && (dwType < MAX_COUNTERS));
  131. _ASSERT(m_pbShMem);
  132. DWORD dwIndex = ((dwType == 0) ? 0 : (DWORD)(dwType/2));
  133. BYTE* pb = (BYTE*)m_pbShMem;
  134. _ASSERT(pb);
  135. pb += MAX_COUNTERS * sizeof(DWORD);
  136. // if lpszInstanceName == NULL, select the first datablock after
  137. // the first INSTANCE_DATA, else iterate until we find the
  138. // right instance name
  139. // TBD insert thread locking
  140. for (DWORD i = 0; i < MAX_INSTANCES; i++)
  141. {
  142. INSTANCE_DATA * pInst = (INSTANCE_DATA *)pb;
  143. _ASSERT(pInst);
  144. pb += sizeof(INSTANCE_DATA);
  145. if (lpszInstanceName == NULL
  146. || (pInst->active && strcmp(pInst->szInstanceName, lpszInstanceName) == 0) )
  147. {
  148. PPERF_COUNTER_BLOCK pCounterBlock = (PPERF_COUNTER_BLOCK)pb;
  149. _ASSERT(pCounterBlock);
  150. PDWORD pdwCounter = ((PDWORD) pCounterBlock) + dwIndex;
  151. _ASSERT(pdwCounter);
  152. InterlockedDecrement((long *)pdwCounter);
  153. return TRUE;
  154. }
  155. pb += (MAX_COUNTERS * sizeof(DWORD));
  156. }
  157. return FALSE;
  158. }
  159. //-------------------------------------------------------------
  160. //
  161. // setCounter
  162. //
  163. //-------------------------------------------------------------
  164. BOOL PassportPerfMon::setCounter ( const DWORD &dwType,
  165. const DWORD &dwValue,
  166. LPCSTR lpszInstanceName )
  167. {
  168. if (!isInited)
  169. {
  170. return FALSE;
  171. }
  172. _ASSERT( (dwType >= 0) && (dwType < MAX_COUNTERS));
  173. _ASSERT(m_pbShMem);
  174. DWORD dwIndex = ((dwType == 0) ? 0 : (DWORD)(dwType/2));
  175. BYTE* pb = (BYTE*)m_pbShMem;
  176. _ASSERT(pb);
  177. pb += MAX_COUNTERS * sizeof(DWORD);
  178. // if lpszInstanceName == NULL, select the first datablock after
  179. // the first INSTANCE_DATA, else iterate until we find the
  180. // right instance name
  181. // TBD insert thread locking
  182. for (DWORD i = 0; i < MAX_INSTANCES; i++)
  183. {
  184. INSTANCE_DATA * pInst = (INSTANCE_DATA *)pb;
  185. _ASSERT(pInst);
  186. pb += sizeof(INSTANCE_DATA);
  187. if (lpszInstanceName == NULL
  188. || (pInst->active && strcmp(pInst->szInstanceName, lpszInstanceName) == 0) )
  189. {
  190. PPERF_COUNTER_BLOCK pCounterBlock = (PPERF_COUNTER_BLOCK)pb;
  191. _ASSERT(pCounterBlock);
  192. PDWORD pdwCounter = ((PDWORD) pCounterBlock) + dwIndex;
  193. _ASSERT(pdwCounter);
  194. InterlockedExchange((LPLONG) pdwCounter, (LONG)dwValue);
  195. return TRUE;
  196. }
  197. pb += (MAX_COUNTERS * sizeof(DWORD));
  198. }
  199. return FALSE;
  200. }
  201. //-------------------------------------------------------------
  202. //
  203. // getCounterValue
  204. //
  205. //-------------------------------------------------------------
  206. BOOL PassportPerfMon::getCounterValue ( DWORD &dwValue,
  207. const DWORD &dwType, LPCSTR lpszInstanceName )
  208. {
  209. if (!isInited)
  210. {
  211. dwValue = 0;
  212. return FALSE;
  213. }
  214. _ASSERT( (dwType >= 0) && (dwType < MAX_COUNTERS));
  215. _ASSERT(m_pbShMem);
  216. DWORD dwIndex = ((dwType == 0) ? 0 : (DWORD)(dwType/2));
  217. BYTE* pb = (BYTE*)m_pbShMem;
  218. _ASSERT(pb);
  219. pb += MAX_COUNTERS * sizeof(DWORD);
  220. // if lpszInstanceName == NULL, select the first datablock after
  221. // the first INSTANCE_DATA, else iterate until we find the
  222. // right instance name
  223. // TBD insert thread locking
  224. for (DWORD i = 0; i < MAX_INSTANCES; i++)
  225. {
  226. INSTANCE_DATA * pInst = (INSTANCE_DATA *)pb;
  227. _ASSERT(pInst);
  228. pb += sizeof(INSTANCE_DATA);
  229. if (lpszInstanceName == NULL
  230. || (pInst->active && strcmp(pInst->szInstanceName, lpszInstanceName) == 0) )
  231. {
  232. PPERF_COUNTER_BLOCK pCounterBlock = (PPERF_COUNTER_BLOCK)pb;
  233. _ASSERT(pCounterBlock);
  234. PDWORD pdwCounter = ((PDWORD) pCounterBlock) + dwIndex;
  235. _ASSERT(pdwCounter);
  236. //
  237. // The counter is aligned with DWORD. Simple read does not need
  238. // the sync operation here.
  239. //
  240. dwValue = (*pdwCounter);
  241. return TRUE;
  242. }
  243. pb += (MAX_COUNTERS * sizeof(DWORD));
  244. }
  245. return TRUE;
  246. }
  247. //-------------------------------------------------------------
  248. //
  249. // setCounterType
  250. //
  251. //-------------------------------------------------------------
  252. BOOL PassportPerfMon::setCounterType ( const DWORD &dwType,
  253. const PassportPerfInterface::COUNTER_SAMPLING_TYPE &counterSampleType)
  254. {
  255. if (!isInited)
  256. {
  257. return FALSE;
  258. }
  259. _ASSERT( (dwType >= 0) && (dwType < MAX_COUNTERS));
  260. _ASSERT(m_pbShMem);
  261. DWORD dwIndex = ((dwType == 0) ? 0 : (DWORD)(dwType/2));
  262. DWORD dwPerfType = 0;
  263. switch ( counterSampleType )
  264. {
  265. case (PassportPerfInterface::COUNTER_COUNTER):
  266. dwPerfType = PERF_COUNTER_COUNTER;
  267. break;
  268. case (PassportPerfInterface::AVERAGE_TIMER):
  269. dwPerfType = PERF_AVERAGE_TIMER;
  270. break;
  271. case (PassportPerfInterface::COUNTER_DELTA):
  272. dwPerfType = PERF_COUNTER_DELTA;
  273. break;
  274. case (PassportPerfInterface::COUNTER_RAWCOUNT):
  275. case (PassportPerfInterface::COUNTER_UNDEFINED):
  276. default:
  277. dwPerfType = PERF_COUNTER_RAWCOUNT;
  278. break;
  279. }
  280. PPERF_COUNTER_BLOCK pCounterBlock = (PPERF_COUNTER_BLOCK)m_pbShMem;
  281. _ASSERT(pCounterBlock);
  282. PDWORD pdwCounter = ((PDWORD) pCounterBlock) + (dwIndex-1);
  283. _ASSERT(pdwCounter);
  284. InterlockedExchange((LPLONG) pdwCounter, (LONG)dwPerfType);
  285. return FALSE;
  286. }
  287. //-------------------------------------------------------------
  288. //
  289. // getCounterType
  290. //
  291. //-------------------------------------------------------------
  292. PassportPerfInterface::COUNTER_SAMPLING_TYPE PassportPerfMon::getCounterType(
  293. const DWORD &dwType ) const
  294. {
  295. if (!isInited)
  296. {
  297. return PassportPerfInterface::COUNTER_UNDEFINED;
  298. }
  299. _ASSERT( (dwType >= 0) && (dwType < MAX_COUNTERS));
  300. _ASSERT(m_pbShMem);
  301. DWORD dwIndex = ((dwType == 0) ? 0 : (DWORD)(dwType/2));
  302. DWORD dwPerfType = 0;
  303. PPERF_COUNTER_BLOCK pCounterBlock = (PPERF_COUNTER_BLOCK)m_pbShMem;
  304. PDWORD pdwCounter = ((PDWORD) pCounterBlock) + (dwIndex-1);
  305. _ASSERT(pdwCounter);
  306. //
  307. // Simple read does not need the sync op here
  308. //
  309. dwPerfType = (*pdwCounter);
  310. switch ( dwPerfType )
  311. {
  312. case (PERF_COUNTER_COUNTER):
  313. return PassportPerfInterface::COUNTER_COUNTER;
  314. case (PERF_AVERAGE_TIMER):
  315. return PassportPerfInterface::AVERAGE_TIMER;
  316. case (PERF_COUNTER_DELTA):
  317. return PassportPerfInterface::COUNTER_DELTA;
  318. case (PERF_COUNTER_RAWCOUNT):
  319. return PassportPerfInterface::COUNTER_RAWCOUNT;
  320. default:
  321. return PassportPerfInterface::COUNTER_UNDEFINED;
  322. }
  323. }
  324. //-------------------------------------------------------------
  325. //
  326. // addInstance
  327. //
  328. //-------------------------------------------------------------
  329. BOOL PassportPerfMon::addInstance( LPCSTR lpszInstanceName )
  330. {
  331. if (!isInited || lpszInstanceName == NULL)
  332. {
  333. return FALSE;
  334. }
  335. if (strlen(lpszInstanceName) >= sizeof(INSTANCENAME)) {
  336. //
  337. // Why not TCHAR here?
  338. //
  339. return FALSE;
  340. }
  341. _ASSERT(m_pbShMem);
  342. BYTE* pb = (BYTE*)m_pbShMem;
  343. _ASSERT(pb);
  344. pb += MAX_COUNTERS * sizeof(DWORD);
  345. DWORD dw = WaitForSingleObject(m_hMutex,INFINITE);
  346. if (dw == WAIT_OBJECT_0)
  347. {
  348. // find if the instance already exists, if so fail
  349. for (DWORD i = 0; i < MAX_INSTANCES; i++)
  350. {
  351. INSTANCE_DATA * pInst = (INSTANCE_DATA *)pb;
  352. _ASSERT(pInst);
  353. if (pInst->active)
  354. {
  355. if (strcmp(pInst->szInstanceName, lpszInstanceName) == 0)
  356. {
  357. ReleaseMutex(m_hMutex);
  358. return FALSE;
  359. }
  360. }
  361. pb += sizeof(INSTANCE_DATA) + (MAX_COUNTERS * sizeof(DWORD));
  362. }
  363. // insert the instance in the first available slot
  364. pb = (BYTE*)m_pbShMem;
  365. _ASSERT(pb);
  366. pb += MAX_COUNTERS * sizeof(DWORD);
  367. for (i = 0; i < MAX_INSTANCES; i++)
  368. {
  369. INSTANCE_DATA * pInst = (INSTANCE_DATA *)pb;
  370. _ASSERT(pInst);
  371. if (!pInst->active)
  372. {
  373. strcpy(pInst->szInstanceName, lpszInstanceName);
  374. pInst->active = TRUE;
  375. InterlockedIncrement(&dwNumInstances);
  376. pb += sizeof(INSTANCE_DATA);
  377. memset(pb,0,(MAX_COUNTERS * sizeof(DWORD)));
  378. ReleaseMutex(m_hMutex);
  379. return TRUE;
  380. }
  381. pb += sizeof(INSTANCE_DATA) + (MAX_COUNTERS * sizeof(DWORD));
  382. }
  383. // didn't find it, fail
  384. ReleaseMutex(m_hMutex);
  385. return FALSE;
  386. }
  387. else
  388. {
  389. ReleaseMutex(m_hMutex);
  390. return FALSE;
  391. }
  392. }
  393. //-------------------------------------------------------------
  394. //
  395. // deleteInstance
  396. //
  397. //-------------------------------------------------------------
  398. BOOL PassportPerfMon::deleteInstance( LPCSTR lpszInstanceName )
  399. {
  400. if (!isInited || lpszInstanceName == NULL)
  401. {
  402. return FALSE;
  403. }
  404. _ASSERT(m_pbShMem);
  405. BYTE* pb = (BYTE*)m_pbShMem;
  406. _ASSERT(pb);
  407. pb += MAX_COUNTERS * sizeof(DWORD);
  408. DWORD dw = WaitForSingleObject(m_hMutex,INFINITE);
  409. if (dw == WAIT_OBJECT_0)
  410. {
  411. // find if the instance already exists, if so set it inactive
  412. for (DWORD i = 0; i < MAX_INSTANCES; i++)
  413. {
  414. INSTANCE_DATA * pInst = (INSTANCE_DATA *)pb;
  415. _ASSERT(pInst);
  416. if (pInst->active && strcmp(pInst->szInstanceName, lpszInstanceName) == 0)
  417. {
  418. pInst->active = FALSE;
  419. InterlockedDecrement(&dwNumInstances);
  420. // zero the data
  421. pb += sizeof(INSTANCE_DATA);
  422. memset(pb,0,(MAX_COUNTERS * sizeof(DWORD)));
  423. ReleaseMutex(m_hMutex);
  424. return TRUE;
  425. }
  426. pb += sizeof(INSTANCE_DATA)+(MAX_COUNTERS * sizeof(DWORD));
  427. }
  428. // didn't find it, fail
  429. ReleaseMutex(m_hMutex);
  430. return FALSE;
  431. }
  432. else
  433. {
  434. ReleaseMutex(m_hMutex);
  435. return FALSE;
  436. }
  437. }
  438. //-------------------------------------------------------------
  439. //
  440. // hasInstances
  441. //
  442. //-------------------------------------------------------------
  443. BOOL PassportPerfMon::hasInstances( void )
  444. {
  445. DWORD dwNum = (DWORD)InterlockedExchangeAdd(&dwNumInstances,0);
  446. if (dwNum > 0)
  447. return TRUE;
  448. else
  449. return FALSE;
  450. }
  451. //-------------------------------------------------------------
  452. //
  453. // numInstances
  454. //
  455. //-------------------------------------------------------------
  456. DWORD PassportPerfMon::numInstances( void )
  457. {
  458. DWORD rv = (DWORD)InterlockedExchangeAdd(&dwNumInstances,0);
  459. return rv;
  460. }
  461. //-------------------------------------------------------------
  462. //
  463. // instanceExists
  464. //
  465. //-------------------------------------------------------------
  466. BOOL PassportPerfMon::instanceExists ( LPCSTR lpszInstanceName )
  467. {
  468. if (!isInited || lpszInstanceName == NULL)
  469. {
  470. return FALSE;
  471. }
  472. _ASSERT(m_pbShMem);
  473. BYTE* pb = (BYTE*)m_pbShMem;
  474. _ASSERT(pb);
  475. DWORD dw = WaitForSingleObject(m_hMutex,INFINITE);
  476. if (dw == WAIT_OBJECT_0)
  477. {
  478. pb += MAX_COUNTERS * sizeof(DWORD);
  479. for (DWORD i = 0; i < MAX_INSTANCES; i++)
  480. {
  481. INSTANCE_DATA * pInst = (INSTANCE_DATA *)pb;
  482. _ASSERT(pInst);
  483. if (pInst->active && strcmp(pInst->szInstanceName, lpszInstanceName) == 0)
  484. {
  485. ReleaseMutex(m_hMutex);
  486. return TRUE;
  487. }
  488. pb += sizeof(INSTANCE_DATA) + (MAX_COUNTERS * sizeof(DWORD));
  489. }
  490. // didn't find it, fail
  491. ReleaseMutex(m_hMutex);
  492. return FALSE;
  493. }
  494. else
  495. {
  496. ReleaseMutex(m_hMutex);
  497. return FALSE;
  498. }
  499. return FALSE;
  500. }