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.

194 lines
5.3 KiB

  1. // ThreadCtlPerf.cpp : main source file for ThreadCtlPerf.exe
  2. //
  3. #include "stdafx.h"
  4. #include <atlframe.h>
  5. #include <atlctrls.h>
  6. #include <atldlgs.h>
  7. #include <atlctrlw.h>
  8. #include "resource.h"
  9. #include "ThreadCtlPerfView.h"
  10. #include "aboutdlg.h"
  11. #include "MainFrm.h"
  12. const UINT knMAX_THREADS = 20;
  13. HMODULE g_hPSAPI = NULL;
  14. // Process memory counters struct.
  15. PROCESS_MEMORY_COUNTERS g_ProcessMem;
  16. // Initial process memory stuff
  17. PROCESS_MEMORY_COUNTERS g_ProcessMemInit;
  18. // Function pointer to GetProcessMemoryInfo.
  19. PFNGETPROCESSMEMORYINFO g_lpfnGetProcessMemoryInfo = NULL;
  20. __int64 g_liFreq = 0;
  21. __int64 g_liLast = 0;
  22. CAppModule _Module;
  23. class CThreadCtlPerfThreadManager
  24. {
  25. public:
  26. // thread init param
  27. struct _RunData
  28. {
  29. LPTSTR lpstrCmdLine;
  30. int nCmdShow;
  31. };
  32. // thread proc
  33. static DWORD WINAPI RunThread(LPVOID lpData)
  34. {
  35. CMessageLoop theLoop;
  36. _Module.AddMessageLoop(&theLoop);
  37. _RunData* pData = (_RunData*)lpData;
  38. CMainFrame wndFrame;
  39. if(wndFrame.CreateEx() == NULL)
  40. {
  41. ATLTRACE(_T("Frame window creation failed!\n"));
  42. return 0;
  43. }
  44. wndFrame.ShowWindow(pData->nCmdShow);
  45. ::SetForegroundWindow(wndFrame); // Win95 needs this
  46. delete pData;
  47. int nRet = theLoop.Run();
  48. _Module.RemoveMessageLoop();
  49. return nRet;
  50. }
  51. DWORD m_dwCount;
  52. HANDLE m_arrThreadHandles[MAXIMUM_WAIT_OBJECTS - 1];
  53. CThreadCtlPerfThreadManager() : m_dwCount(0)
  54. { }
  55. // Operations
  56. DWORD AddThread(LPTSTR lpstrCmdLine, int nCmdShow)
  57. {
  58. if(m_dwCount == (MAXIMUM_WAIT_OBJECTS - 1))
  59. {
  60. ::MessageBox(NULL, _T("ERROR: Cannot create ANY MORE threads!!!"), _T("ThreadCtlPerf"), MB_OK);
  61. return 0;
  62. }
  63. _RunData* pData = new _RunData;
  64. pData->lpstrCmdLine = lpstrCmdLine;
  65. pData->nCmdShow = nCmdShow;
  66. DWORD dwThreadID;
  67. HANDLE hThread = ::CreateThread(NULL, 0, RunThread, pData, 0, &dwThreadID);
  68. if(hThread == NULL)
  69. {
  70. ::MessageBox(NULL, _T("ERROR: Cannot create thread!!!"), _T("ThreadCtlPerf"), MB_OK);
  71. return 0;
  72. }
  73. m_arrThreadHandles[m_dwCount] = hThread;
  74. m_dwCount++;
  75. return dwThreadID;
  76. }
  77. void RemoveThread(DWORD dwIndex)
  78. {
  79. ::CloseHandle(m_arrThreadHandles[dwIndex]);
  80. if(dwIndex != (m_dwCount - 1))
  81. m_arrThreadHandles[dwIndex] = m_arrThreadHandles[m_dwCount - 1];
  82. m_dwCount--;
  83. }
  84. int Run(LPTSTR lpstrCmdLine, int nCmdShow)
  85. {
  86. MSG msg;
  87. // force message queue to be created
  88. ::PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
  89. (g_lpfnGetProcessMemoryInfo)(GetCurrentProcess(), &g_ProcessMemInit, sizeof(g_ProcessMem));
  90. ::QueryPerformanceFrequency( (LARGE_INTEGER*) &g_liFreq);
  91. ::QueryPerformanceCounter( (LARGE_INTEGER*) &g_liLast);
  92. UINT nMaxThreads = 0;
  93. nMaxThreads = wcstol(lpstrCmdLine, 0, 10);
  94. if (nMaxThreads == 0)
  95. nMaxThreads = knMAX_THREADS;
  96. AddThread(lpstrCmdLine, nCmdShow);
  97. int nRet = m_dwCount;
  98. DWORD dwRet;
  99. while(m_dwCount > 0)
  100. {
  101. dwRet = ::MsgWaitForMultipleObjects(m_dwCount, m_arrThreadHandles, FALSE, INFINITE, QS_ALLINPUT);
  102. if(dwRet == 0xFFFFFFFF)
  103. ::MessageBox(NULL, _T("ERROR: Wait for multiple objects failed!!!"), _T("ThreadCtlPerf"), MB_OK);
  104. else if(dwRet >= WAIT_OBJECT_0 && dwRet <= (WAIT_OBJECT_0 + m_dwCount - 1))
  105. RemoveThread(dwRet - WAIT_OBJECT_0);
  106. else if(dwRet == (WAIT_OBJECT_0 + m_dwCount))
  107. {
  108. ::GetMessage(&msg, NULL, 0, 0);
  109. if(msg.message == WM_USER && m_dwCount < nMaxThreads)
  110. AddThread(_T(""), SW_SHOWNORMAL);
  111. else if(msg.message == WM_USER + 1)
  112. m_dwCount = 0;
  113. else
  114. ::MessageBeep((UINT)-1);
  115. }
  116. else
  117. ::MessageBeep((UINT)-1);
  118. }
  119. return nRet;
  120. }
  121. };
  122. int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPTSTR lpstrCmdLine, int nCmdShow)
  123. {
  124. HRESULT hRes = ::CoInitialize(NULL);
  125. // If you are running on NT 4.0 or higher you can use the following call instead to
  126. // make the EXE free threaded. This means that calls come in on a random RPC thread.
  127. // HRESULT hRes = ::CoInitializeEx(NULL, COINIT_MULTITHREADED);
  128. ATLASSERT(SUCCEEDED(hRes));
  129. #if (_WIN32_IE >= 0x0300)
  130. INITCOMMONCONTROLSEX iccx;
  131. iccx.dwSize = sizeof(iccx);
  132. //iccx.dwICC = ICC_COOL_CLASSES | ICC_BAR_CLASSES;
  133. iccx.dwICC = 0x3FFF;
  134. BOOL bRet = ::InitCommonControlsEx(&iccx);
  135. bRet;
  136. ATLASSERT(bRet);
  137. #else
  138. ::InitCommonControls();
  139. #endif
  140. hRes = _Module.Init(NULL, hInstance);
  141. ATLASSERT(SUCCEEDED(hRes));
  142. g_hPSAPI = ::LoadLibrary(_T("PSAPI.DLL"));
  143. int nRet = -1;
  144. if (g_hPSAPI)
  145. {
  146. // Load the function:
  147. g_lpfnGetProcessMemoryInfo = (PFNGETPROCESSMEMORYINFO)::GetProcAddress(g_hPSAPI, "GetProcessMemoryInfo");
  148. if (NULL != g_lpfnGetProcessMemoryInfo)
  149. {
  150. CThreadCtlPerfThreadManager mgr;
  151. nRet = mgr.Run(lpstrCmdLine, nCmdShow);
  152. }
  153. ::FreeLibrary(g_hPSAPI);
  154. }
  155. _Module.Term();
  156. ::CoUninitialize();
  157. return nRet;
  158. }