|
|
// StresDlg.cpp : implementation file
//
#include "stdafx.h"
#include "CpuStres.h"
#include "StresDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__; #endif
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog { public: CAboutDlg();
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX }; //}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected: //{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP() };
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) { //{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) //{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CStressDlg dialog
CStressDlg::CStressDlg(CWnd* pParent /*=NULL*/) : CDialog(CStressDlg::IDD, pParent) { //{{AFX_DATA_INIT(CStressDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); m_dwProcessPriority = NORMAL_PRIORITY_CLASS;
m_ActivityValue[0] = SLOW_ACTIVITY; m_ActivityValue[1] = SLOW_ACTIVITY; m_ActivityValue[2] = SLOW_ACTIVITY; m_ActivityValue[3] = SLOW_ACTIVITY;
m_PriorityValue[0] = THREAD_PRIORITY_NORMAL; m_PriorityValue[1] = THREAD_PRIORITY_NORMAL; m_PriorityValue[2] = THREAD_PRIORITY_NORMAL; m_PriorityValue[3] = THREAD_PRIORITY_NORMAL;
m_Active[0] = TRUE; m_Active[1] = FALSE; m_Active[2] = FALSE; m_Active[3] = FALSE; m_ThreadHandle[0] = NULL; m_ThreadHandle[1] = NULL; m_ThreadHandle[2] = NULL; m_ThreadHandle[3] = NULL;
m_dwLoopValue = 0x00010000;
m_pMemory = NULL; m_dwVASize = 0; m_dwRandomScale = 1; }
void CStressDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CStressDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CStressDlg, CDialog) //{{AFX_MSG_MAP(CStressDlg)
ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_BN_CLICKED(IDC_1_ACTIVE, On1Active) ON_CBN_SELCHANGE(IDC_1_ACTIVITY, OnSelchange1Activity) ON_CBN_SELCHANGE(IDC_1_PRIORITY, OnSelchange1Priority) ON_BN_CLICKED(IDC_2_ACTIVE, On2Active) ON_CBN_SELCHANGE(IDC_2_ACTIVITY, OnSelchange2Activity) ON_CBN_SELCHANGE(IDC_2_PRIORITY, OnSelchange2Priority) ON_BN_CLICKED(IDC_3_ACTIVE, On3Active) ON_CBN_SELCHANGE(IDC_3_ACTIVITY, OnSelchange3Activity) ON_CBN_SELCHANGE(IDC_3_PRIORITY, OnSelchange3Priority) ON_BN_CLICKED(IDC_4_ACTIVE, On4Active) ON_CBN_SELCHANGE(IDC_4_ACTIVITY, OnSelchange4Activity) ON_CBN_SELCHANGE(IDC_4_PRIORITY, OnSelchange4Priority) ON_CBN_SELCHANGE(IDC_PROCESS_PRIORITY, OnSelchangeProcessPriority) ON_EN_KILLFOCUS(IDC_SHARED_MEM_SIZE, OnKillfocusSharedMemSize) ON_EN_CHANGE(IDC_SHARED_MEM_SIZE, OnChangeSharedMemSize) ON_BN_CLICKED(IDC_USE_MEMORY, OnUseMemory) ON_WM_CLOSE() ON_WM_DESTROY() //}}AFX_MSG_MAP
END_MESSAGE_MAP()
// disable optimization since it will remove the "do-nothing" loops
#pragma optimize ("", off)
DWORD CStressDlg::OnePercentCalibration(DWORD dwLoopValue) { // find how many loops consume 10% of this processor
LARGE_INTEGER liPerfFreq; LONGLONG llOnePercent; LARGE_INTEGER liStartTime; LARGE_INTEGER liEndTime; LONGLONG llDiff; LONGLONG llMinDiff; DWORD dwPriorityClass; DWORD dwThreadPriority; HANDLE hProcess; HANDLE hThread; DWORD dwLoopCounter; DWORD dwReturn; LONGLONG llResult; BOOL bGoodSample = FALSE; DWORD dwAttemptCount = 5;
dwReturn = dwLoopValue; QueryPerformanceFrequency (&liPerfFreq); llOnePercent = liPerfFreq.QuadPart / 100; // the calibration run must take at least 50 ms
llMinDiff = liPerfFreq.QuadPart / 20;
hProcess = GetCurrentProcess(); hThread = GetCurrentThread(); dwPriorityClass = GetPriorityClass (hProcess); dwThreadPriority = GetThreadPriority (hThread);
SetPriorityClass (hProcess, HIGH_PRIORITY_CLASS); SetThreadPriority (hThread, THREAD_PRIORITY_HIGHEST);
while (!bGoodSample && dwAttemptCount) { // start timing
QueryPerformanceCounter (&liStartTime); // do a trial loop
for (dwLoopCounter = dwLoopValue; dwLoopCounter; dwLoopCounter--); // end timing
QueryPerformanceCounter (&liEndTime); llDiff = liEndTime.QuadPart - liStartTime.QuadPart; if (llDiff > llMinDiff) { bGoodSample = TRUE; } else { // increase the loop counter value by a factor of 10
dwLoopValue *= 10; dwAttemptCount--; } } // restore the priority since we're done with the critical part
SetPriorityClass (hProcess, dwPriorityClass); SetThreadPriority (hThread, dwThreadPriority);
if (!bGoodSample) { MessageBox("Unable to calibrate delay loop"); } else { // findout what the 1% count is
if (llDiff != llOnePercent) { // then adjust the initial loop value was too big so reduce
llResult = llOnePercent * dwLoopValue / llDiff; if (llResult & 0xFFFFFFFF00000000) { // this processor is TOO FAST! so don't change.
} else { dwReturn = (DWORD)(llResult & 0x00000000FFFFFFFF); } } } return dwReturn; }
DWORD WorkerProc (LPDWORD dwArg) { DWORD dwLoopCounter; LPTHREAD_INFO_BLOCK pInfo; DWORD dwStartingValue; DWORD dwLocalValue; DWORD dwLocalIndex;
pInfo = (LPTHREAD_INFO_BLOCK)dwArg; dwStartingValue = pInfo->Dlg->m_dwLoopValue;
srand( (unsigned)time( NULL ) );
while (pInfo->Dlg->m_Active[pInfo->dwId]) { for (dwLoopCounter = dwStartingValue; dwLoopCounter; dwLoopCounter--) { if (pInfo->Dlg->m_pMemory != NULL) { do { dwLocalIndex = rand(); dwLocalIndex *= pInfo->Dlg->m_dwRandomScale; } while (dwLocalIndex >= pInfo->Dlg->m_dwVASize); pInfo->Dlg->m_pMemory[dwLocalIndex] = dwLocalIndex; dwLocalValue = pInfo->Dlg->m_pMemory[dwLocalIndex]; // reduce loop iterations to account for
// accessing memory
if (pInfo->Dlg->m_Active[pInfo->dwId]) { if (dwLoopCounter > 20) { dwLoopCounter -= 20; } else { dwLoopCounter = 1; } } else { break; // out of loop
} } } if (pInfo->Dlg->m_ActivityValue[pInfo->dwId] > 0) { Sleep (pInfo->Dlg->m_ActivityValue[pInfo->dwId]); } } pInfo->Dlg->m_ThreadHandle[pInfo->dwId] = NULL; delete pInfo; return 0; } #pragma optimize ("", on)
void CStressDlg::CreateWorkerThread (DWORD dwId) { DWORD dwThreadId; LPTHREAD_INFO_BLOCK pInfo;
// then start a new thread
pInfo = new THREAD_INFO_BLOCK; if (!pInfo) { return; } pInfo->Dlg = this; pInfo->dwId = dwId; m_Active[dwId] = TRUE; m_ThreadHandle[dwId] = CreateThread ( NULL, 0, (LPTHREAD_START_ROUTINE)WorkerProc, (LPVOID)pInfo, 0, &dwThreadId); if (m_ThreadHandle[dwId] == NULL) { m_Active[dwId] = FALSE; delete pInfo; } else { // establish thread priority
SetThreadPriority ( m_ThreadHandle[dwId], m_PriorityValue[dwId]); } }
void CStressDlg::SetThreadActivity (CComboBox * cActivityCombo, DWORD dwId) { switch (cActivityCombo->GetCurSel()) { case 0: m_ActivityValue[dwId] = SLOW_ACTIVITY; break; case 1: m_ActivityValue[dwId] = MEDIUM_ACTIVITY; break; case 2: m_ActivityValue[dwId] = HIGH_ACTIVITY; break; case 3: m_ActivityValue[dwId] = HOG_ACTIVITY; break; } }
void CStressDlg::SetThreadPriorityLevel (CComboBox * cPriorityCombo, DWORD dwId) { LONG lLastError = ERROR_SUCCESS;
switch (cPriorityCombo->GetCurSel()) { case 0: m_PriorityValue[dwId] = (DWORD)THREAD_PRIORITY_IDLE; break; case 1: m_PriorityValue[dwId] = (DWORD)THREAD_PRIORITY_LOWEST; break; case 2: m_PriorityValue[dwId] = (DWORD)THREAD_PRIORITY_BELOW_NORMAL; break; case 3: m_PriorityValue[dwId] = (DWORD)THREAD_PRIORITY_NORMAL; break; case 4: m_PriorityValue[dwId] = (DWORD)THREAD_PRIORITY_ABOVE_NORMAL; break; case 5: m_PriorityValue[dwId] = (DWORD)THREAD_PRIORITY_HIGHEST; break; case 6: m_PriorityValue[dwId] = (DWORD)THREAD_PRIORITY_TIME_CRITICAL; break; } if (m_ThreadHandle[dwId] != NULL) { if (!SetThreadPriority (m_ThreadHandle[dwId], m_PriorityValue[dwId])) { lLastError = GetLastError (); } } // else no thread open
}
/////////////////////////////////////////////////////////////////////////////
// CStressDlg message handlers
BOOL CStressDlg::OnInitDialog() { CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE); CString strAboutMenu; strAboutMenu.LoadString(IDS_ABOUTBOX); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); }
// calibrate loop counter
m_dwLoopValue = OnePercentCalibration (m_dwLoopValue) * 10;
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// set the priority of this thread to "highest" so the UI will be
// responsive
SetThreadPriority (GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
// enable thread 1 & disable all others
((CComboBox *)GetDlgItem(IDC_PROCESS_PRIORITY))->SetCurSel(1);
CheckDlgButton (IDC_1_ACTIVE, 1); ((CComboBox *)GetDlgItem(IDC_1_PRIORITY))->SetCurSel(3); ((CComboBox *)GetDlgItem(IDC_1_ACTIVITY))->SetCurSel(0);
CheckDlgButton (IDC_2_ACTIVE, 0); ((CComboBox *)GetDlgItem(IDC_2_PRIORITY))->SetCurSel(3); ((CComboBox *)GetDlgItem(IDC_2_ACTIVITY))->SetCurSel(0);
CheckDlgButton (IDC_3_ACTIVE, 0); ((CComboBox *)GetDlgItem(IDC_3_PRIORITY))->SetCurSel(3); ((CComboBox *)GetDlgItem(IDC_3_ACTIVITY))->SetCurSel(0);
CheckDlgButton (IDC_4_ACTIVE, 0); ((CComboBox *)GetDlgItem(IDC_4_PRIORITY))->SetCurSel(3); ((CComboBox *)GetDlgItem(IDC_4_ACTIVITY))->SetCurSel(0);
// set the process priority
OnSelchangeProcessPriority();
// start the first thread
On1Active();
// don't access memory by default
CheckDlgButton (IDC_USE_MEMORY, 0); (GetDlgItem (IDC_SHARED_MEM_SIZE))->EnableWindow (FALSE);
return TRUE; // return TRUE unless you set the focus to a control
}
void CStressDlg::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID & 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); } else { CDialog::OnSysCommand(nID, lParam); } }
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CStressDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon); } else { CDialog::OnPaint(); } }
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CStressDlg::OnQueryDragIcon() { return (HCURSOR) m_hIcon; }
void CStressDlg::On1Active() { DWORD dwId = 0;
if (IsDlgButtonChecked(IDC_1_ACTIVE)) { if (m_ThreadHandle[dwId] == NULL) { CreateWorkerThread (dwId); } else { // thread is already running
} } else { m_Active[dwId] = FALSE; m_ThreadHandle[dwId] = NULL; } }
void CStressDlg::OnSelchange1Activity() { CComboBox * cActivityCombo; DWORD dwId = 0; cActivityCombo = (CComboBox *)GetDlgItem (IDC_1_ACTIVITY); SetThreadActivity (cActivityCombo, dwId); }
void CStressDlg::OnSelchange1Priority() { CComboBox * cPriorityCombo; DWORD dwId = 0; cPriorityCombo = (CComboBox *)GetDlgItem (IDC_1_PRIORITY); SetThreadPriorityLevel (cPriorityCombo, dwId); }
void CStressDlg::On2Active() { DWORD dwId = 1;
if (IsDlgButtonChecked(IDC_2_ACTIVE)) { if (m_ThreadHandle[dwId] == NULL) { CreateWorkerThread (dwId); } else { // thread is already running
} } else { m_Active[dwId] = FALSE; m_ThreadHandle[dwId] = NULL; } }
void CStressDlg::OnSelchange2Activity() { CComboBox * cActivityCombo; DWORD dwId = 1; cActivityCombo = (CComboBox *)GetDlgItem (IDC_2_ACTIVITY); SetThreadActivity (cActivityCombo, dwId); }
void CStressDlg::OnSelchange2Priority() { CComboBox * cPriorityCombo; DWORD dwId = 1; cPriorityCombo = (CComboBox *)GetDlgItem (IDC_2_PRIORITY); SetThreadPriorityLevel (cPriorityCombo, dwId); }
void CStressDlg::On3Active() { DWORD dwId = 2;
if (IsDlgButtonChecked(IDC_3_ACTIVE)) { if (m_ThreadHandle[dwId] == NULL) { CreateWorkerThread (dwId); } else { // thread is already running
} } else { m_Active[dwId] = FALSE; m_ThreadHandle[dwId] = NULL; } }
void CStressDlg::OnSelchange3Activity() { CComboBox * cActivityCombo; DWORD dwId = 2; cActivityCombo = (CComboBox *)GetDlgItem (IDC_3_ACTIVITY); SetThreadActivity (cActivityCombo, dwId); }
void CStressDlg::OnSelchange3Priority() { CComboBox * cPriorityCombo; DWORD dwId = 2; cPriorityCombo = (CComboBox *)GetDlgItem (IDC_3_PRIORITY); SetThreadPriorityLevel (cPriorityCombo, dwId); }
void CStressDlg::On4Active() { DWORD dwId = 3;
if (IsDlgButtonChecked(IDC_4_ACTIVE)) { if (m_ThreadHandle[dwId] == NULL) { CreateWorkerThread (dwId); } else { // thread is already running
} } else { m_Active[dwId] = FALSE; CloseHandle (m_ThreadHandle[dwId]); m_ThreadHandle[dwId] = NULL; } }
void CStressDlg::OnSelchange4Activity() { CComboBox * cActivityCombo; DWORD dwId = 3; cActivityCombo = (CComboBox *)GetDlgItem (IDC_4_ACTIVITY); SetThreadActivity (cActivityCombo, dwId); }
void CStressDlg::OnSelchange4Priority() { CComboBox * cPriorityCombo; DWORD dwId = 3; cPriorityCombo = (CComboBox *)GetDlgItem (IDC_4_PRIORITY); SetThreadPriorityLevel (cPriorityCombo, dwId); }
void CStressDlg::OnOK() { CDialog::OnOK(); }
void CStressDlg::OnSelchangeProcessPriority() {
CComboBox * cPriorityCombo; DWORD dwPriorityClass; cPriorityCombo = (CComboBox *)GetDlgItem (IDC_PROCESS_PRIORITY);
switch (cPriorityCombo->GetCurSel()) { case 0: dwPriorityClass = IDLE_PRIORITY_CLASS; break; case 1: dwPriorityClass = NORMAL_PRIORITY_CLASS; break; case 2: dwPriorityClass = HIGH_PRIORITY_CLASS; break; } SetPriorityClass (GetCurrentProcess(), dwPriorityClass); }
void CStressDlg::OnKillfocusSharedMemSize() { return; }
void CStressDlg::OnChangeSharedMemSize() { CString csMemSize; TCHAR szOldValue[MAX_PATH]; DWORD dwMemSize;
csMemSize.Empty(); GetDlgItemText (IDC_SHARED_MEM_SIZE, csMemSize); dwMemSize = _tcstoul ((LPCTSTR)csMemSize, NULL, 10); dwMemSize *= 1024 / sizeof(DWORD);
if (dwMemSize != m_dwVASize) { // threads must be stopped to change memory size
if (m_Active[0] || m_Active[1] || m_Active[2] || m_Active[3]) { MessageBox ( TEXT("All threads must be stopped before this value can be changed")); _stprintf (szOldValue, TEXT("%d"), ((m_dwVASize * sizeof(DWORD))/1024)); (GetDlgItem(IDC_SHARED_MEM_SIZE))->SetWindowText(szOldValue); return; } else { if (m_pMemory != NULL) { delete (m_pMemory); m_pMemory = NULL; m_dwVASize = 0; } m_dwVASize = dwMemSize; m_pMemory = new DWORD[m_dwVASize]; if (m_pMemory == NULL) { m_dwVASize = 0; } } } }
void CStressDlg::OnUseMemory() { CString csMemSize; DWORD dwMemSize; BOOL bState;
if (m_Active[0] || m_Active[1] || m_Active[2] || m_Active[3]) { MessageBox (TEXT("All threads must be stopped before this value can be changed")); bState = !IsDlgButtonChecked(IDC_USE_MEMORY); //revert state
} else { if (IsDlgButtonChecked(IDC_USE_MEMORY)) { // if no memory is allocated, then allocate it
if (m_pMemory != NULL) { delete (m_pMemory); m_pMemory = NULL; m_dwVASize = 0; } //get va size
csMemSize.Empty(); GetDlgItemText (IDC_SHARED_MEM_SIZE, csMemSize); dwMemSize = _tcstoul ((LPCTSTR)csMemSize, NULL, 10); m_dwVASize = dwMemSize * 1024 / sizeof(DWORD); m_pMemory = new DWORD[m_dwVASize]; if (m_pMemory == NULL) { m_dwVASize = 0; } else { m_dwRandomScale = (m_dwVASize / RAND_MAX) + 1; } bState = TRUE; } else { // button is unchecked so free memory
if (m_pMemory != NULL) { delete (m_pMemory); m_pMemory = NULL; m_dwVASize = 0; } bState = FALSE; } } CheckDlgButton (IDC_USE_MEMORY, bState); (GetDlgItem (IDC_SHARED_MEM_SIZE))->EnableWindow (bState); }
void CStressDlg::OnClose() { // stop threads first
m_Active[0] = FALSE; m_Active[1] = FALSE; m_Active[2] = FALSE; m_Active[3] = FALSE;
// wait for the threads to finish
while (m_ThreadHandle[0] || m_ThreadHandle[1] || m_ThreadHandle[2] || m_ThreadHandle[3]) { Sleep(100); }
// free memory block
if (m_pMemory != NULL) { delete (m_pMemory); m_pMemory = NULL; m_dwVASize = 0; } CDialog::OnClose(); }
void CStressDlg::OnDestroy() { CDialog::OnDestroy(); }
|