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.

1523 lines
38 KiB

  1. /*++
  2. Copyright (c) 1990 Microsoft Corporation
  3. Module Name:
  4. Wperf.c
  5. Abstract:
  6. Win32 application to display performance statictics.
  7. Author:
  8. Ken Reneris hacked into pperf.exe
  9. original code from Mark Enstrom
  10. Environment:
  11. Win32
  12. --*/
  13. //
  14. // set variable to define global variables
  15. //
  16. #include <nt.h>
  17. #include <ntrtl.h>
  18. #include <nturtl.h>
  19. #include <windows.h>
  20. #include <errno.h>
  21. #include <malloc.h>
  22. #include <stdlib.h>
  23. #include <stdio.h>
  24. #include "pperf.h"
  25. #include "..\pstat.h"
  26. //
  27. // global handles
  28. //
  29. HANDLE hInst;
  30. extern UCHAR Buffer[];
  31. extern HANDLE DriverHandle;
  32. //
  33. // Selected Display Mode (read from wp2.ini), default set here.
  34. //
  35. DISPLAY_ITEM *PerfGraphList;
  36. WINPERF_INFO WinperfInfo;
  37. VOID SnapNull (PDISPLAY_ITEM);
  38. VOID SnapPrivateInfo (PDISPLAY_ITEM);
  39. VOID SnapInterrupts (PDISPLAY_ITEM);
  40. VOID SnapCsTest (PDISPLAY_ITEM);
  41. ULONG DefaultDisplayMode = DISPLAY_MODE_TOTAL;
  42. ULONG UseGlobalMax, LogIt;
  43. ULONG GlobalMax;
  44. PDISPLAY_ITEM Calc1, Calc2;
  45. BOOLEAN LazyOp;
  46. #define MAX_EVENTS 2
  47. struct {
  48. ULONG EventId;
  49. PUCHAR ShortName;
  50. PUCHAR PerfName;
  51. } *Counters;
  52. struct {
  53. ULONG WhichCounter;
  54. ULONG ComboBoxIndex;
  55. PDISPLAY_ITEM pWhichGraph;
  56. BOOLEAN R0;
  57. BOOLEAN R3;
  58. UCHAR na[2];
  59. } ActiveCounters [MAX_EVENTS];
  60. SETEVENT CounterEvents[MAX_EVENTS];
  61. typedef struct {
  62. ULONG IdSel;
  63. PDISPLAY_ITEM WhichGraph;
  64. ULONG State;
  65. VOID (*Fnc)(PDISPLAY_ITEM);
  66. ULONG Param;
  67. PUCHAR Name;
  68. } GENCOUNTER, *PGENCOUNTER;
  69. GENCOUNTER GenCounts[] = {
  70. IDM_SCALE, NULL, 0, NULL, 0, NULL,
  71. IDM_LOGIT, NULL, 0, NULL, 0, NULL,
  72. IDM_SPIN_ACQUIRE, NULL, 0, SnapPrivateInfo, OFFSET(PSTATS, SpinLockAcquires), "KRes[0]",
  73. IDM_SPIN_COLL, NULL, 0, SnapPrivateInfo, OFFSET(PSTATS, SpinLockCollisions), "KRes[1]",
  74. IDM_SPIN_SPIN, NULL, 0, SnapPrivateInfo, OFFSET(PSTATS, SpinLockSpins), "KRes[2]",
  75. IDM_IRQL, NULL, 0, SnapPrivateInfo, OFFSET(PSTATS, Irqls), "KRes[3]",
  76. IDM_INT, NULL, 0, SnapInterrupts, 0, "Interrupts",
  77. // IDM_PERCENT, NULL, 0, SnapPercent, 0, "Percent 1-2",
  78. // to track checked state
  79. IDM_P5_R0_0, NULL, 0, NULL, 0, NULL,
  80. IDM_P5_R3_0, NULL, 0, NULL, 0, NULL,
  81. IDM_P5_K_0, NULL, 0, NULL, 0, NULL,
  82. IDM_P5_R0_1, NULL, 0, NULL, 0, NULL,
  83. IDM_P5_R3_1, NULL, 0, NULL, 0, NULL,
  84. IDM_P5_K_1, NULL, 0, NULL, 0, NULL,
  85. // eol
  86. 0, NULL, 0, NULL, 0, NULL
  87. };
  88. VOID
  89. InitComboBox (
  90. HWND hDlg,
  91. ULONG id,
  92. ULONG counter
  93. );
  94. VOID
  95. SetGenPerf (
  96. HWND hDlg,
  97. PGENCOUNTER GenCount
  98. );
  99. int
  100. __cdecl
  101. main(USHORT argc, CHAR **argv)
  102. /*++
  103. Routine Description:
  104. Windows entry point routine
  105. Arguments:
  106. Return Value:
  107. status of operation
  108. Revision History:
  109. 03-21-91 Initial code
  110. --*/
  111. {
  112. //
  113. //
  114. //
  115. HANDLE hInstance = GetModuleHandle(NULL);
  116. HANDLE hPrevInstance = (HANDLE)NULL;
  117. INT nCmdShow = SW_SHOWDEFAULT;
  118. USHORT _argc = argc;
  119. CHAR **_argv = argv;
  120. MSG msg;
  121. HBRUSH BackBrush;
  122. //
  123. // check for other instances of this program
  124. //
  125. BackBrush = CreateSolidBrush(RGB(192,192,192));
  126. if (!InitApplication(hInstance,BackBrush)) {
  127. //DbgPrint("Init Application fails\n");
  128. return (FALSE);
  129. }
  130. //
  131. // Perform initializations that apply to a specific instance
  132. //
  133. if (!InitInstance(hInstance, nCmdShow)){
  134. //DbgPrint("Init Instance fails\n");
  135. return (FALSE);
  136. }
  137. //
  138. // Acquire and dispatch messages until a WM_QUIT message is received.
  139. //
  140. while (GetMessage(&msg, // message structure
  141. (HWND)NULL, // handle of window receiving the message
  142. (UINT)NULL, // lowest message to examine
  143. (UINT)NULL)) // highest message to examine
  144. {
  145. TranslateMessage(&msg); // Translates virtual key codes
  146. DispatchMessage(&msg); // Dispatches message to window
  147. }
  148. DeleteObject(BackBrush);
  149. return (msg.wParam); // Returns the value from PostQuitMessage
  150. }
  151. BOOL
  152. InitApplication(
  153. HANDLE hInstance,
  154. HBRUSH hBackground)
  155. /*++
  156. Routine Description:
  157. Initializes window data and registers window class.
  158. Arguments:
  159. hInstance - current instance
  160. hBackground - background fill brush
  161. Return Value:
  162. status of operation
  163. Revision History:
  164. 02-17-91 Initial code
  165. --*/
  166. {
  167. WNDCLASS wc;
  168. BOOL ReturnStatus;
  169. //
  170. // Fill in window class structure with parameters that describe the
  171. // main window.
  172. //
  173. wc.style = CS_DBLCLKS; // Class style(s).
  174. wc.lpfnWndProc = (WNDPROC)MainWndProc; // Function to retrieve messages for
  175. // windows of this class.
  176. wc.cbClsExtra = 0; // No per-class extra data.
  177. wc.cbWndExtra = 0; // No per-window extra data.
  178. wc.hInstance = hInstance; // Application that owns the class.
  179. wc.hIcon = LoadIcon(hInstance, //
  180. MAKEINTRESOURCE(WINPERF_ICON)); // Load Winperf icon
  181. wc.hCursor = LoadCursor((HANDLE)NULL, IDC_ARROW); // Load default cursor
  182. wc.hbrBackground = hBackground;; // Use background passed to routine
  183. wc.lpszMenuName = "pperfMenu"; // Name of menu resource in .RC file.
  184. wc.lpszClassName = "PPerfClass"; // Name used in call to CreateWindow.
  185. ReturnStatus = RegisterClass(&wc);
  186. return(ReturnStatus);
  187. }
  188. BOOL
  189. InitInstance(
  190. HANDLE hInstance,
  191. int nCmdShow
  192. )
  193. /*++
  194. Routine Description:
  195. Save instance handle and create main window. This function performs
  196. initialization tasks that cannot be shared by multiple instances.
  197. Arguments:
  198. hInstance - Current instance identifier.
  199. nCmdShow - Param for first ShowWindow() call.
  200. Return Value:
  201. status of operation
  202. Revision History:
  203. 02-17-91 Initial code
  204. --*/
  205. {
  206. DWORD WindowStyle;
  207. //
  208. // Save the instance handle in a static variable, which will be used in
  209. // many subsequent calls from this application to Windows.
  210. //
  211. hInst = hInstance;
  212. //
  213. // init the window position and size to be in the upper corner of
  214. // the screen, 200x100
  215. //
  216. //
  217. // What I want here is a way to get the WINDOW dimensions
  218. //
  219. WinperfInfo.WindowPositionX = 640 - 250;
  220. WinperfInfo.WindowPositionY = 0;
  221. WinperfInfo.WindowSizeX = 250;
  222. WinperfInfo.WindowSizeY = 100;
  223. //
  224. // read profile data from .ini file
  225. //
  226. // InitProfileData(&WinperfInfo);
  227. WinperfInfo.hMenu = LoadMenu(hInstance,"pperfMenu");
  228. //
  229. // Create a main window for this application instance.
  230. //
  231. WinperfInfo.hWndMain = CreateWindow(
  232. "PPerfClass", // See RegisterClass() call.
  233. "x86 Perf Meter", // Text for window title bar.
  234. WS_OVERLAPPEDWINDOW, // window style
  235. WinperfInfo.WindowPositionX, // Default horizontal position.
  236. WinperfInfo.WindowPositionY, // Default vertical position.
  237. WinperfInfo.WindowSizeX, // Default width.
  238. WinperfInfo.WindowSizeY, // Default height.
  239. (HWND)NULL, // Overlapped windows have no parent.
  240. (HMENU)NULL, // Use the window class menu.
  241. hInstance, // This instance owns this window.
  242. (LPVOID)NULL // Pointer not needed.
  243. );
  244. //
  245. // Show menu initially
  246. //
  247. WindowStyle = GetWindowLong(WinperfInfo.hWndMain,GWL_STYLE);
  248. WindowStyle = (WindowStyle & (~STYLE_DISABLE_MENU)) | STYLE_ENABLE_MENU;
  249. SetMenu(WinperfInfo.hWndMain,WinperfInfo.hMenu);
  250. SetWindowLong(WinperfInfo.hWndMain,GWL_STYLE,WindowStyle);
  251. SetWindowPos(WinperfInfo.hWndMain, (HWND)NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_DRAWFRAME);
  252. ShowWindow(WinperfInfo.hWndMain,SW_SHOW);
  253. WinperfInfo.DisplayMode=STYLE_ENABLE_MENU;
  254. WinperfInfo.DisplayMenu = TRUE;
  255. //
  256. // If window could not be created, return "failure"
  257. //
  258. if (!WinperfInfo.hWndMain) {
  259. return (FALSE);
  260. }
  261. //
  262. // Make the window visible; update its client area; and return "success"
  263. //
  264. SetFocus(WinperfInfo.hWndMain);
  265. ShowWindow(WinperfInfo.hWndMain, SW_SHOWNORMAL);
  266. UpdateWindow(WinperfInfo.hWndMain);
  267. return (TRUE);
  268. }
  269. VOID
  270. InitPossibleEventList()
  271. {
  272. UCHAR buffer[400];
  273. ULONG i, Count;
  274. NTSTATUS status;
  275. PEVENTID Event;
  276. IO_STATUS_BLOCK IOSB;
  277. //
  278. // Initialize possible counters
  279. //
  280. // determine how many events there are
  281. Event = (PEVENTID) buffer;
  282. Count = 0;
  283. do {
  284. *((PULONG) buffer) = Count;
  285. Count += 1;
  286. status = NtDeviceIoControlFile(
  287. DriverHandle,
  288. (HANDLE) NULL, // event
  289. (PIO_APC_ROUTINE) NULL,
  290. (PVOID) NULL,
  291. &IOSB,
  292. PSTAT_QUERY_EVENTS,
  293. buffer, // input buffer
  294. sizeof (buffer),
  295. NULL, // output buffer
  296. 0
  297. );
  298. } while (NT_SUCCESS(status));
  299. Counters = malloc(sizeof(*Counters) * Count);
  300. if (Counters == NULL) {
  301. printf("Memory allocation failed.\n");
  302. exit(1);
  303. }
  304. Count -= 1;
  305. for (i=0; i < Count; i++) {
  306. *((PULONG) buffer) = i;
  307. NtDeviceIoControlFile(
  308. DriverHandle,
  309. (HANDLE) NULL, // event
  310. (PIO_APC_ROUTINE) NULL,
  311. (PVOID) NULL,
  312. &IOSB,
  313. PSTAT_QUERY_EVENTS,
  314. buffer, // input buffer
  315. sizeof (buffer),
  316. NULL, // output buffer
  317. 0
  318. );
  319. Counters[i].EventId = Event->EventId;
  320. Counters[i].ShortName = _strdup (Event->Buffer);
  321. Counters[i].PerfName = _strdup (Event->Buffer + Event->DescriptionOffset);
  322. }
  323. Counters[i].EventId = 0;
  324. Counters[i].ShortName = NULL;
  325. Counters[i].PerfName = NULL;
  326. }
  327. LONG APIENTRY
  328. MainWndProc(
  329. HWND hWnd,
  330. UINT message,
  331. DWORD wParam,
  332. LONG lParam
  333. )
  334. /*++
  335. Routine Description:
  336. Process messages.
  337. Arguments:
  338. hWnd - window hande
  339. message - type of message
  340. wParam - additional information
  341. lParam - additional information
  342. Return Value:
  343. status of operation
  344. Revision History:
  345. 02-17-91 Initial code
  346. --*/
  347. {
  348. int DialogResult;
  349. PAINTSTRUCT ps;
  350. PDISPLAY_ITEM pPerf, p;
  351. ULONG l, i, x, y;
  352. HDC hDC;
  353. //
  354. // process each message
  355. //
  356. switch (message) {
  357. //
  358. // create window
  359. //
  360. case WM_CREATE:
  361. {
  362. HDC hDC = GetDC(hWnd);
  363. BOOLEAN Fit;
  364. UINT Index;
  365. //
  366. // make brushes and pens
  367. //
  368. WinperfInfo.hBluePen = CreatePen(PS_SOLID,1,RGB(0,0,128));
  369. WinperfInfo.hDotPen = CreatePen(PS_DOT,1,RGB(0,0,0));
  370. WinperfInfo.hPPen[0] = CreatePen(PS_SOLID,1,RGB(255, 0, 0));
  371. WinperfInfo.hPPen[1] = CreatePen(PS_SOLID,1,RGB( 0, 255, 0));
  372. WinperfInfo.hPPen[2] = CreatePen(PS_SOLID,1,RGB(255, 255, 0));
  373. WinperfInfo.hPPen[3] = CreatePen(PS_SOLID,1,RGB(255, 0, 255));
  374. WinperfInfo.hPPen[4] = CreatePen(PS_SOLID,1,RGB(128, 0, 0));
  375. WinperfInfo.hPPen[5] = CreatePen(PS_SOLID,1,RGB( 0, 128, 0));
  376. WinperfInfo.hPPen[6] = CreatePen(PS_SOLID,1,RGB(128, 128, 0));
  377. WinperfInfo.hPPen[7] = CreatePen(PS_SOLID,1,RGB(128, 0, 128));
  378. WinperfInfo.hPPen[8] = CreatePen(PS_SOLID,1,RGB( 0, 0, 128));
  379. WinperfInfo.hPPen[9] = CreatePen(PS_SOLID,1,RGB( 0, 128, 128));
  380. WinperfInfo.hPPen[10]= CreatePen(PS_SOLID,1,RGB(128, 128, 128));
  381. // the other 20 pens will just reuse these handles
  382. WinperfInfo.hBackground = CreateSolidBrush(RGB(192,192,192));
  383. WinperfInfo.hLightBrush = CreateSolidBrush(RGB(255,255,255));
  384. WinperfInfo.hDarkBrush = CreateSolidBrush(RGB(128,128,128));
  385. WinperfInfo.hRedBrush = CreateSolidBrush(RGB(255,000,000));
  386. WinperfInfo.hGreenBrush = CreateSolidBrush(RGB(000,255,000));
  387. WinperfInfo.hBlueBrush = CreateSolidBrush(RGB(000,000,255));
  388. //
  389. // create thee fonts using NT default font families
  390. //
  391. WinperfInfo.SmallFont = CreateFont(8,
  392. 0,
  393. 0,
  394. 0,
  395. 400,
  396. FALSE,
  397. FALSE,
  398. FALSE,
  399. ANSI_CHARSET,
  400. OUT_DEFAULT_PRECIS,
  401. CLIP_DEFAULT_PRECIS,
  402. DRAFT_QUALITY,
  403. DEFAULT_PITCH,
  404. "Small Fonts");
  405. WinperfInfo.MediumFont = CreateFont(10,
  406. 0,
  407. 0,
  408. 0,
  409. 400,
  410. FALSE,
  411. FALSE,
  412. FALSE,
  413. ANSI_CHARSET,
  414. OUT_DEFAULT_PRECIS,
  415. CLIP_DEFAULT_PRECIS,
  416. DRAFT_QUALITY,
  417. DEFAULT_PITCH,
  418. "Times New Roman");
  419. WinperfInfo.LargeFont = CreateFont(14,
  420. 0,
  421. 0,
  422. 0,
  423. 400,
  424. FALSE,
  425. FALSE,
  426. FALSE,
  427. ANSI_CHARSET,
  428. OUT_DEFAULT_PRECIS,
  429. CLIP_DEFAULT_PRECIS,
  430. DRAFT_QUALITY,
  431. DEFAULT_PITCH,
  432. "Times New Roman");
  433. //
  434. // create a system timer event to call performance gathering routines by.
  435. //
  436. WinperfInfo.TimerId = SetTimer(hWnd,(UINT)TIMER_ID,(UINT)1000 * DELAY_SECONDS,(TIMERPROC)NULL);
  437. //
  438. // init performance routines
  439. //
  440. WinperfInfo.NumberOfProcessors = InitPerfInfo();
  441. // copy pen's for remaining processor breakout
  442. for (i=11; i < WinperfInfo.NumberOfProcessors; i++) {
  443. WinperfInfo.hPPen[i] = WinperfInfo.hPPen[i % 12];
  444. }
  445. if (!WinperfInfo.NumberOfProcessors) {
  446. MessageBox(hWnd,"P5Stat driver not installed","Winperf",MB_OK);
  447. DestroyWindow(hWnd);
  448. }
  449. //
  450. // init display variables
  451. //
  452. RefitWindows (hWnd, hDC);
  453. //
  454. // release the DC handle
  455. //
  456. ReleaseDC(hWnd,hDC);
  457. }
  458. break;
  459. //
  460. // re-size
  461. //
  462. case WM_SIZE:
  463. {
  464. int i;
  465. HDC hDC = GetDC(hWnd);
  466. RECT ClientRect;
  467. BOOLEAN Fit;
  468. //
  469. // get size of cleint area
  470. //
  471. GetWindowRect(hWnd,&ClientRect);
  472. WinperfInfo.WindowPositionX = ClientRect.left;
  473. WinperfInfo.WindowPositionY = ClientRect.top;
  474. WinperfInfo.WindowSizeX = ClientRect.right - ClientRect.left;
  475. WinperfInfo.WindowSizeY = ClientRect.bottom - ClientRect.top;
  476. RefitWindows(hWnd, NULL);
  477. }
  478. break;
  479. case WM_MOVE:
  480. {
  481. HDC hDC = GetDC(hWnd);
  482. RECT ClientRect;
  483. //
  484. // get size of cleint area
  485. //
  486. GetWindowRect(hWnd,&ClientRect);
  487. WinperfInfo.WindowPositionX = ClientRect.left;
  488. WinperfInfo.WindowPositionY = ClientRect.top;
  489. WinperfInfo.WindowSizeX = ClientRect.right - ClientRect.left;
  490. WinperfInfo.WindowSizeY = ClientRect.bottom - ClientRect.top;
  491. ReleaseDC(hWnd,hDC);
  492. }
  493. break;
  494. //
  495. // command from application menu
  496. //
  497. case WM_COMMAND:
  498. switch (wParam){
  499. //
  500. // exit window
  501. //
  502. case IDM_EXIT:
  503. DestroyWindow(hWnd);
  504. break;
  505. //
  506. // about command
  507. //
  508. case IDM_SELECT:
  509. DialogResult = DialogBox(hInst,MAKEINTRESOURCE(IDM_SEL_DLG),hWnd,(DLGPROC)SelectDlgProc);
  510. if (DialogResult == DIALOG_SUCCESS) {
  511. RefitWindows(hWnd, NULL);
  512. }
  513. break;
  514. case IDM_DISPLAY_TOTAL:
  515. SetDefaultDisplayMode (hWnd, DISPLAY_MODE_TOTAL);
  516. break;
  517. case IDM_DISPLAY_BREAKDOWN:
  518. SetDefaultDisplayMode (hWnd, DISPLAY_MODE_BREAKDOWN);
  519. break;
  520. case IDM_DISPLAY_PER_PROCESSOR:
  521. SetDefaultDisplayMode (hWnd, DISPLAY_MODE_PER_PROCESSOR);
  522. break;
  523. case IDM_TOPMOST:
  524. //SetWindowPos( hWnd, HWND_NOTOPMOST, 0, 0, 0, 0,
  525. // SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
  526. SetWindowPos( hWnd, HWND_TOPMOST, 0, 0, 0, 0,
  527. SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
  528. break;
  529. case IDM_THUNK:
  530. DialogBox(hInst,MAKEINTRESOURCE(IDM_THUNK_DLG),hWnd,(DLGPROC)ThunkDlgProc);
  531. break;
  532. case IDM_HACK:
  533. DoCSTest(hWnd);
  534. RefitWindows(hWnd, NULL);
  535. break;
  536. default:
  537. return (DefWindowProc(hWnd, message, wParam, lParam));
  538. }
  539. break;
  540. case WM_PAINT:
  541. //
  542. // repaint the window
  543. //
  544. {
  545. int i;
  546. HDC hDC = BeginPaint(hWnd,&ps);
  547. SelectObject(hDC,GetStockObject(NULL_BRUSH));
  548. for (pPerf=PerfGraphList; pPerf; pPerf=pPerf->Next) {
  549. DrawFrame(hDC,pPerf);
  550. DrawPerfText(hDC,pPerf);
  551. DrawPerfGraph(hDC,pPerf);
  552. }
  553. EndPaint(hWnd,&ps);
  554. }
  555. break;
  556. case WM_TIMER:
  557. {
  558. int i;
  559. HDC hDC = GetDC(hWnd);
  560. //
  561. // Calc new information
  562. //
  563. CalcPerf(PerfGraphList);
  564. //
  565. // If some lazy op, then perform it
  566. //
  567. if (LazyOp) {
  568. pPerf=PerfGraphList;
  569. while (pPerf) {
  570. if (pPerf->DeleteMe) {
  571. pPerf = SetDisplayToFalse (pPerf);
  572. } else {
  573. pPerf = pPerf->Next;
  574. }
  575. }
  576. RefitWindows(hWnd, hDC);
  577. LazyOp = FALSE;
  578. }
  579. //
  580. // update all performance information
  581. //
  582. for (pPerf=PerfGraphList; pPerf; pPerf=pPerf->Next) {
  583. if (pPerf->ChangeScale) {
  584. DrawPerfText(hDC,pPerf);
  585. DrawPerfGraph(hDC,pPerf);
  586. } else {
  587. DrawPerfText(hDC,pPerf);
  588. ShiftPerfGraph(hDC,pPerf);
  589. }
  590. }
  591. ReleaseDC(hWnd,hDC);
  592. }
  593. break;
  594. //
  595. // right double click
  596. //
  597. case WM_NCRBUTTONDBLCLK:
  598. case WM_RBUTTONDBLCLK:
  599. Calc1 = NULL;
  600. y = HIWORD(lParam);
  601. x = LOWORD(lParam);
  602. for (pPerf=PerfGraphList; pPerf; pPerf=pPerf->Next) {
  603. if (x > pPerf->PositionX && x < pPerf->PositionX+pPerf->Width &&
  604. y > pPerf->PositionY && y < pPerf->PositionY+pPerf->Height) {
  605. if (pPerf->IsCalc) {
  606. SetDisplayToFalse (pPerf);
  607. FreeDisplayItem (pPerf);
  608. RefitWindows (hWnd, NULL);
  609. break;
  610. }
  611. switch (pPerf->DisplayMode) {
  612. case DISPLAY_MODE_TOTAL: l = DISPLAY_MODE_BREAKDOWN; break;
  613. case DISPLAY_MODE_BREAKDOWN: l = DISPLAY_MODE_PER_PROCESSOR; break;
  614. case DISPLAY_MODE_PER_PROCESSOR: l = DISPLAY_MODE_TOTAL; break;
  615. }
  616. pPerf->DisplayMode = l;
  617. hDC = BeginPaint(hWnd,&ps);
  618. DrawPerfGraph(hDC,pPerf); // redraw graph in new mode
  619. EndPaint(hWnd,&ps);
  620. break;
  621. }
  622. }
  623. break;
  624. switch (DefaultDisplayMode) {
  625. case DISPLAY_MODE_TOTAL: l = DISPLAY_MODE_BREAKDOWN; break;
  626. case DISPLAY_MODE_BREAKDOWN: l = DISPLAY_MODE_PER_PROCESSOR; break;
  627. case DISPLAY_MODE_PER_PROCESSOR: l = DISPLAY_MODE_TOTAL; break;
  628. }
  629. DefaultDisplayMode = l;
  630. for (pPerf=PerfGraphList; pPerf; pPerf=pPerf->Next) {
  631. pPerf->DisplayMode = l;
  632. hDC = BeginPaint(hWnd,&ps);
  633. DrawPerfGraph(hDC,pPerf); // redraw graph in new mode
  634. EndPaint(hWnd,&ps);
  635. }
  636. break;
  637. //
  638. // handle a double click
  639. //
  640. case WM_NCLBUTTONDBLCLK:
  641. case WM_LBUTTONDBLCLK:
  642. {
  643. DWORD WindowStyle;
  644. //
  645. // get old window style, take out caption and menu
  646. //
  647. Calc1 = NULL;
  648. if (!IsIconic(hWnd)) {
  649. if (WinperfInfo.DisplayMenu) {
  650. WindowStyle = GetWindowLong(hWnd,GWL_STYLE);
  651. WindowStyle = (WindowStyle & (~STYLE_ENABLE_MENU)) | STYLE_DISABLE_MENU;
  652. SetMenu(hWnd,NULL);
  653. SetWindowLong(hWnd,GWL_STYLE,WindowStyle);
  654. SetWindowPos(hWnd, (HWND)NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_DRAWFRAME);
  655. ShowWindow(hWnd,SW_SHOW);
  656. WinperfInfo.DisplayMode=STYLE_DISABLE_MENU;
  657. WinperfInfo.DisplayMenu = FALSE;
  658. } else {
  659. WindowStyle = GetWindowLong(hWnd,GWL_STYLE);
  660. WindowStyle = (WindowStyle & (~STYLE_DISABLE_MENU)) | STYLE_ENABLE_MENU;
  661. SetMenu(hWnd,WinperfInfo.hMenu);
  662. SetWindowLong(hWnd,GWL_STYLE,WindowStyle);
  663. SetWindowPos(hWnd, (HWND)NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_DRAWFRAME);
  664. ShowWindow(hWnd,SW_SHOW);
  665. WinperfInfo.DisplayMode=STYLE_ENABLE_MENU;
  666. WinperfInfo.DisplayMenu = TRUE;
  667. }
  668. } else {
  669. DefWindowProc(hWnd, message, wParam, lParam);
  670. }
  671. }
  672. break;
  673. case WM_NCRBUTTONDOWN:
  674. case WM_RBUTTONDOWN:
  675. y = HIWORD(lParam);
  676. x = LOWORD(lParam);
  677. for (pPerf=PerfGraphList; pPerf; pPerf=pPerf->Next) {
  678. if (x > pPerf->PositionX && x < pPerf->PositionX+pPerf->Width &&
  679. y > pPerf->PositionY && y < pPerf->PositionY+pPerf->Height) {
  680. if (!Calc1) {
  681. Calc1 = pPerf;
  682. break;
  683. }
  684. if (Calc1 != pPerf) {
  685. Calc2 = pPerf;
  686. DialogBox(hInst,MAKEINTRESOURCE(IDM_CALC_DLG),hWnd,(DLGPROC)CalcDlgProc);
  687. Calc1 = Calc2 = NULL;
  688. break;
  689. }
  690. break;
  691. }
  692. }
  693. break;
  694. //
  695. // enable dragging with mouse in non-client
  696. //
  697. case WM_NCHITTEST:
  698. {
  699. lParam = DefWindowProc(hWnd, message, wParam, lParam);
  700. if ((WinperfInfo.DisplayMenu==FALSE) && (lParam == HTCLIENT)) {
  701. return(HTCAPTION);
  702. } else {
  703. return(lParam);
  704. }
  705. }
  706. break;
  707. case WM_DESTROY:
  708. {
  709. UINT Index;
  710. //
  711. // Save profile info
  712. //
  713. // SaveProfileData(&WinperfInfo);
  714. //
  715. // Delete Windows Objects
  716. //
  717. KillTimer(hWnd,TIMER_ID);
  718. DeleteObject(WinperfInfo.hBluePen);
  719. for (i=0; i < 12; i++) {
  720. DeleteObject(WinperfInfo.hPPen[i]);
  721. }
  722. for (pPerf=PerfGraphList; pPerf; pPerf=pPerf->Next) {
  723. DeleteMemoryContext(pPerf);
  724. }
  725. //
  726. // Destroy window
  727. //
  728. PostQuitMessage(0);
  729. }
  730. break;
  731. default:
  732. //
  733. // Passes message on if unproccessed
  734. //
  735. return (DefWindowProc(hWnd, message, wParam, lParam));
  736. }
  737. return ((LONG)NULL);
  738. }
  739. BOOL
  740. APIENTRY SelectDlgProc(
  741. HWND hDlg,
  742. unsigned message,
  743. DWORD wParam,
  744. LONG lParam
  745. )
  746. /*++
  747. Routine Description:
  748. Process message for select dialog box.
  749. Arguments:
  750. hDlg - window handle of the dialog box
  751. message - type of message
  752. wParam - message-specific information
  753. lParam - message-specific information
  754. Return Value:
  755. status of operation
  756. Revision History:
  757. 03-21-91 Initial code
  758. --*/
  759. {
  760. PDISPLAY_ITEM pPerf;
  761. UINT ButtonState;
  762. UINT Index, i;
  763. switch (message) {
  764. case WM_INITDIALOG:
  765. InitComboBox (hDlg, IDM_P5_GEN1, 0);
  766. InitComboBox (hDlg, IDM_P5_GEN2, 1);
  767. for (i=0; GenCounts[i].IdSel; i++) {
  768. SendDlgItemMessage(
  769. hDlg,
  770. GenCounts[i].IdSel,
  771. BM_SETCHECK,
  772. GenCounts[i].State,
  773. 0
  774. );
  775. }
  776. return (TRUE);
  777. case WM_COMMAND:
  778. switch(wParam) {
  779. //
  780. // end function
  781. //
  782. case IDOK:
  783. case IDM_ACCEPT:
  784. SetP5Perf (hDlg, IDM_P5_GEN1, 0);
  785. SetP5Perf (hDlg, IDM_P5_GEN2, 1);
  786. for (i=0; GenCounts[i].IdSel; i++) {
  787. SetGenPerf (hDlg, GenCounts+i);
  788. }
  789. UseGlobalMax = GenCounts[0].State;
  790. LogIt = GenCounts[1].State;
  791. for (pPerf=PerfGraphList; pPerf; pPerf=pPerf->Next) {
  792. pPerf->MaxToUse =
  793. UseGlobalMax ? &GlobalMax : &pPerf->Max;
  794. }
  795. if (wParam == IDOK) {
  796. EndDialog(hDlg, DIALOG_SUCCESS);
  797. } else {
  798. RefitWindows (NULL, NULL);
  799. }
  800. return (TRUE);
  801. case IDCANCEL:
  802. EndDialog(hDlg, DIALOG_CANCEL );
  803. return (TRUE);
  804. }
  805. }
  806. return (FALSE);
  807. }
  808. VOID
  809. RefitWindows (HWND hWnd, HDC CurhDC)
  810. {
  811. PDISPLAY_ITEM pPerf;
  812. BOOLEAN fit;
  813. ULONG Index;
  814. HDC hDC;
  815. hWnd = WinperfInfo.hWndMain;
  816. hDC = CurhDC;
  817. if (!CurhDC) {
  818. hDC = GetDC(hWnd);
  819. }
  820. fit = FitPerfWindows(hWnd,hDC,PerfGraphList);
  821. if (!fit) {
  822. //DbgPrint("Fit Fails\n");
  823. }
  824. for (pPerf=PerfGraphList; pPerf; pPerf=pPerf->Next) {
  825. DeleteMemoryContext(pPerf);
  826. CalcDrawFrame(pPerf);
  827. if (!CreateMemoryContext(hDC,pPerf)) {
  828. MessageBox(hWnd,"Error Allocating Memory","Winperf",MB_OK);
  829. DestroyWindow(hWnd);
  830. break;
  831. }
  832. }
  833. InvalidateRect(hWnd,(LPRECT)NULL,TRUE);
  834. if (!CurhDC) {
  835. ReleaseDC(hWnd,hDC);
  836. }
  837. }
  838. VOID
  839. InitComboBox (HWND hDlg, ULONG id, ULONG counter)
  840. {
  841. HWND ComboList;
  842. ULONG i, nIndex;
  843. ComboList = GetDlgItem(hDlg, id);
  844. SendMessage(ComboList, CB_RESETCONTENT, 0, 0);
  845. SendMessage(ComboList, CB_SETITEMDATA, 0L, 0L);
  846. if (Counters) {
  847. for (i=0; Counters[i].PerfName; i++) {
  848. nIndex = SendMessage(
  849. ComboList,
  850. CB_ADDSTRING,
  851. 0,
  852. (DWORD) Counters[i].PerfName
  853. );
  854. SendMessage(
  855. ComboList,
  856. CB_SETITEMDATA,
  857. nIndex,
  858. (DWORD) i
  859. );
  860. }
  861. }
  862. SendMessage(ComboList, CB_SETCURSEL, ActiveCounters[counter].ComboBoxIndex, 0L);
  863. }
  864. VOID
  865. SetP5Perf (HWND hDlg, ULONG IdCombo, ULONG counter)
  866. {
  867. static PUCHAR NameSuffix[] = { "", " (R0)", " (R3)", "" };
  868. HWND ComboList;
  869. ULONG nIndex, Mega, DU, BSEncoding, flag;
  870. PDISPLAY_ITEM pPerf;
  871. PUCHAR name;
  872. SETEVENT Event;
  873. ComboList = GetDlgItem(hDlg, IdCombo);
  874. nIndex = (int)SendMessage(ComboList, CB_GETCURSEL, 0, 0);
  875. ActiveCounters[counter].ComboBoxIndex = nIndex;
  876. memset (&Event, 0, sizeof (Event));
  877. Event.Active = TRUE;
  878. Event.KernelMode = SendDlgItemMessage(hDlg,IdCombo+1,BM_GETCHECK,0,0) ? TRUE : FALSE;
  879. Event.UserMode = SendDlgItemMessage(hDlg,IdCombo+2,BM_GETCHECK,0,0) ? TRUE : FALSE;
  880. BSEncoding = (Event.UserMode << 1) | Event.KernelMode;
  881. Mega = SendDlgItemMessage(hDlg,IdCombo+3,BM_GETCHECK,0,0) ? 1 : 0;
  882. //DU = SendDlgItemMessage(hDlg,IdCombo+3,BM_GETCHECK,0,0) ? 1 : 0;
  883. DU = 0;
  884. // get encoding for counter
  885. if ((!Event.KernelMode && !Event.UserMode) || nIndex == -1) {
  886. // no counter selected, done
  887. if (ActiveCounters[counter].pWhichGraph != NULL) {
  888. ClearGraph (ActiveCounters[counter].pWhichGraph);
  889. }
  890. return ;
  891. }
  892. // select counter
  893. nIndex = SendMessage(ComboList, CB_GETITEMDATA, nIndex, 0);
  894. Event.EventId = Counters[nIndex].EventId;
  895. ActiveCounters[counter].WhichCounter = nIndex;
  896. if (ActiveCounters[counter].pWhichGraph == NULL) {
  897. ActiveCounters[counter].pWhichGraph = AllocateDisplayItem();
  898. }
  899. pPerf = ActiveCounters[counter].pWhichGraph; // which window
  900. sprintf (pPerf->PerfName, "%s%s", Counters[nIndex].PerfName, NameSuffix[BSEncoding]);
  901. flag = TRUE;
  902. if (Mega != pPerf->Mega || memcmp (&Event, CounterEvents+counter, sizeof (Event))) {
  903. flag = FALSE;
  904. CounterEvents[counter] = Event;
  905. SetCounterEvents (CounterEvents, sizeof CounterEvents);
  906. }
  907. pPerf->SnapData = SnapPrivateInfo; // generic snap
  908. pPerf->SnapParam1 = OFFSET(PSTATS, Counters[ counter ]);
  909. pPerf->Mega = Mega;
  910. SetDisplayToTrue (pPerf, IdCombo);
  911. if (flag) {
  912. // didn't change types
  913. return ;
  914. }
  915. // clear graph
  916. flag = pPerf->CalcId;
  917. ClearGraph (pPerf);
  918. pPerf->Mega = Mega;
  919. pPerf->CalcId = flag;
  920. SetDisplayToTrue (pPerf, IdCombo);
  921. UpdateInternalStats ();
  922. pPerf->SnapData (pPerf);
  923. UpdateInternalStats ();
  924. pPerf->SnapData (pPerf);
  925. }
  926. VOID
  927. ClearGraph (
  928. PDISPLAY_ITEM pPerf
  929. )
  930. {
  931. ULONG i, j;
  932. PULONG pDL;
  933. SetDisplayToFalse (pPerf);
  934. pPerf->Mega = FALSE;
  935. for (i=0 ; i < WinperfInfo.NumberOfProcessors+1; i++) {
  936. pDL = pPerf->DataList[i];
  937. for (j=0; j<DATA_LIST_LENGTH; j++) {
  938. *(pDL++) = 0;
  939. }
  940. }
  941. pPerf->Max = 1;
  942. pPerf->CurrentDrawingPos = 0;
  943. pPerf->ChangeScale = TRUE;
  944. }
  945. VOID
  946. SetGenPerf (HWND hDlg, PGENCOUNTER GenCount)
  947. {
  948. PDISPLAY_ITEM pPerf;
  949. ULONG ButtonState;
  950. GenCount->State = SendDlgItemMessage(hDlg,GenCount->IdSel,BM_GETCHECK,0,0);
  951. if (GenCount->Fnc == NULL) {
  952. return ;
  953. }
  954. if (GenCount->WhichGraph == NULL) {
  955. GenCount->WhichGraph = AllocateDisplayItem();
  956. }
  957. pPerf = GenCount->WhichGraph;
  958. if (!GenCount->State) {
  959. ClearGraph (pPerf);
  960. return ;
  961. }
  962. strcpy (pPerf->PerfName, GenCount->Name);
  963. pPerf->SnapData = GenCount->Fnc;
  964. pPerf->SnapParam1 = GenCount->Param;
  965. pPerf->SnapData (pPerf);
  966. SetDisplayToTrue (pPerf, GenCount->IdSel);
  967. }
  968. VOID
  969. SetDisplayToTrue (
  970. PDISPLAY_ITEM pPerf,
  971. ULONG sort
  972. )
  973. {
  974. PDISPLAY_ITEM p, *pp;
  975. Calc1 = NULL;
  976. if (pPerf->Display) { // already displayed
  977. return ; // just return
  978. }
  979. if (pPerf->CalcId) {
  980. sprintf (pPerf->DispName, "%d. %s", pPerf->CalcId, pPerf->PerfName);
  981. } else {
  982. strcpy (pPerf->DispName, pPerf->PerfName);
  983. }
  984. pPerf->DispNameLen = strlen (pPerf->DispName);
  985. pPerf->Display = TRUE; // set to display
  986. pPerf->sort = sort;
  987. // check to see if grap is already listed
  988. for (p = PerfGraphList; p; p = p->Next) {
  989. if (p == pPerf) {
  990. // already in the active list, ret
  991. return ;
  992. }
  993. }
  994. // put graph in perfered sorting order
  995. for (pp = &PerfGraphList; *pp; pp = &(*pp)->Next) {
  996. if ((*pp)->sort > sort) {
  997. break;
  998. }
  999. }
  1000. pPerf->Next = *pp;
  1001. *pp = pPerf;
  1002. }
  1003. PDISPLAY_ITEM
  1004. SetDisplayToFalse (
  1005. PDISPLAY_ITEM pPerf
  1006. )
  1007. {
  1008. PDISPLAY_ITEM *p, p1;
  1009. for (p = &PerfGraphList; *p; p = &(*p)->Next) { // remove graph from
  1010. if (*p == pPerf) { // active list
  1011. *p = pPerf->Next;
  1012. break;
  1013. }
  1014. }
  1015. if (pPerf->CalcId) {
  1016. Calc1 = Calc2 = NULL;
  1017. for (p1 = PerfGraphList; p1; p1 = p1->Next) {
  1018. p1->CalcPercent[0] = NULL;
  1019. p1->CalcPercent[1] = NULL;
  1020. }
  1021. }
  1022. pPerf->CalcId = 0;
  1023. pPerf->Display = FALSE; // clear flag
  1024. return *p;
  1025. }
  1026. VOID
  1027. SetDefaultDisplayMode (HWND hWnd, ULONG mode)
  1028. {
  1029. HDC hDC;
  1030. PDISPLAY_ITEM pPerf;
  1031. PAINTSTRUCT ps;
  1032. hDC = BeginPaint(hWnd,&ps);
  1033. DefaultDisplayMode = mode;
  1034. for (pPerf=PerfGraphList; pPerf; pPerf=pPerf->Next) {
  1035. if (pPerf->IsPercent) {
  1036. continue;
  1037. }
  1038. pPerf->DisplayMode = DefaultDisplayMode;
  1039. DrawPerfGraph(hDC,pPerf); // redraw graph in new mode
  1040. }
  1041. EndPaint(hWnd,&ps);
  1042. }
  1043. PDISPLAY_ITEM
  1044. AllocateDisplayItem()
  1045. {
  1046. PDISPLAY_ITEM pPerf;
  1047. UINT Index1, Index2;
  1048. PULONG pDL;
  1049. pPerf = malloc(sizeof (DISPLAY_ITEM));
  1050. if (pPerf == NULL) {
  1051. printf("Memory allocation failed.\n");
  1052. exit(1);
  1053. }
  1054. RtlZeroMemory (pPerf, sizeof (DISPLAY_ITEM));
  1055. pPerf->Display = FALSE;
  1056. pPerf->Max = 1;
  1057. pPerf->SnapData = SnapNull;
  1058. pPerf->DisplayMode = DefaultDisplayMode;
  1059. pPerf->AutoTotal = TRUE;
  1060. pPerf->MaxToUse = &pPerf->Max;
  1061. strcpy (pPerf->PerfName, "?");
  1062. strcpy (pPerf->DispName, "?");
  1063. pPerf->DispNameLen = 1;
  1064. for (Index1=0 ; Index1 < WinperfInfo.NumberOfProcessors+1; Index1++) {
  1065. pDL = malloc (DATA_LIST_LENGTH * sizeof (ULONG));
  1066. if (pDL == NULL) {
  1067. printf("Memory allocation failed.\n");
  1068. exit(1);
  1069. }
  1070. pPerf->DataList[Index1] = pDL;
  1071. RtlZeroMemory (pDL, sizeof(ULONG) * DATA_LIST_LENGTH);
  1072. }
  1073. return pPerf;
  1074. }
  1075. VOID
  1076. FreeDisplayItem(PDISPLAY_ITEM pPerf)
  1077. {
  1078. ULONG i;
  1079. for (i=0 ; i < WinperfInfo.NumberOfProcessors+1; i++) {
  1080. free (pPerf->DataList[i]);
  1081. }
  1082. free (pPerf);
  1083. }
  1084. //
  1085. // ************** HACKTEST
  1086. //
  1087. ULONG CsCount[32*32];
  1088. struct s_ThreadInfo {
  1089. PULONG Counter;
  1090. HDC MemoryDC;
  1091. HWND hWnd;
  1092. } ThreadInfo[32];
  1093. DWORD
  1094. WorkerCsTestThread (
  1095. struct s_ThreadInfo *TInfo
  1096. )
  1097. {
  1098. HDC hDC;
  1099. HDC hDCmem;
  1100. HBITMAP hbm;
  1101. ULONG i;
  1102. hDC = GetDC(TInfo->hWnd);
  1103. hDCmem= CreateCompatibleDC(hDC);
  1104. hbm = CreateCompatibleBitmap(hDC,100,100);
  1105. SelectObject(hDCmem,hbm);
  1106. for (i = 0; i < (ULONG)-1 ; i++) {
  1107. (*TInfo->Counter)++;
  1108. //GetPixel(hDC, 9999, 9999);
  1109. //BitBlt(hDC, 1, 1, 20, 20, TInfo->MemoryDC, 0, 0, SRCCOPY);
  1110. PatBlt(hDCmem,0,0,20,20,PATCOPY);
  1111. }
  1112. ReleaseDC(TInfo->hWnd,hDC);
  1113. return 0;
  1114. }
  1115. VOID
  1116. DoCSTest(HWND hWnd)
  1117. {
  1118. static ULONG ThreadCount = 0;
  1119. PDISPLAY_ITEM pPerf;
  1120. DWORD junk;
  1121. if (ThreadCount >= 32) {
  1122. return ;
  1123. }
  1124. pPerf = AllocateDisplayItem();
  1125. ThreadInfo[ThreadCount].Counter = &CsCount[ThreadCount];
  1126. ThreadInfo[ThreadCount].MemoryDC = pPerf->MemoryDC;
  1127. ThreadInfo[ThreadCount].hWnd = hWnd;
  1128. CreateThread (NULL, 0,
  1129. (LPTHREAD_START_ROUTINE) WorkerCsTestThread,
  1130. (LPVOID) &ThreadInfo[ThreadCount],
  1131. 0,
  1132. &junk);
  1133. pPerf->SnapData = SnapCsTest;
  1134. pPerf->SnapParam1 = ThreadCount;
  1135. ThreadCount++;
  1136. sprintf (pPerf->PerfName, "CS trans %ld", ThreadCount);
  1137. SetDisplayToTrue (pPerf, 1);
  1138. }
  1139. VOID
  1140. SnapCsTest (
  1141. IN OUT PDISPLAY_ITEM pPerf
  1142. )
  1143. {
  1144. ULONG i;
  1145. pPerf->CurrentDataPoint[1] = CsCount[pPerf->SnapParam1];
  1146. CsCount[pPerf->SnapParam1] = 0;
  1147. }