mirror of
https://github.com/zodiacon/WindowsInternals
synced 2026-08-09 13:18:09 +00:00
165 lines
4.6 KiB
C++
165 lines
4.6 KiB
C++
// AffinityDlg.cpp : implementation file
|
|
//
|
|
|
|
#include "stdafx.h"
|
|
#include "CPUStressEx.h"
|
|
#include "AffinityDlg.h"
|
|
#include "afxdialogex.h"
|
|
#include "Globals.h"
|
|
#include "Thread.h"
|
|
|
|
// CAffinityDlg dialog
|
|
|
|
IMPLEMENT_DYNAMIC(CAffinityDlg, CDialogEx)
|
|
|
|
CAffinityDlg::CAffinityDlg(bool affinity, CThread* pThread, const CString& title, CWnd* pParent)
|
|
: CDialogEx(IDD_AFFINITY, pParent), m_Affinity(affinity), m_Title(title), m_pThread(pThread) {
|
|
}
|
|
|
|
CAffinityDlg::CAffinityDlg(const CString& title, CWnd* pParent) : CDialogEx(IDD_AFFINITY, pParent), m_Title(title), m_Process(true), m_Affinity(true) {
|
|
}
|
|
|
|
CAffinityDlg::~CAffinityDlg() {
|
|
}
|
|
|
|
void CAffinityDlg::DoDataExchange(CDataExchange* pDX) {
|
|
CDialogEx::DoDataExchange(pDX);
|
|
if(!m_Affinity) {
|
|
DDX_Radio(pDX, IDC_FIRST, m_IdealCPU);
|
|
}
|
|
}
|
|
|
|
BEGIN_MESSAGE_MAP(CAffinityDlg, CDialogEx)
|
|
ON_BN_CLICKED(IDC_SELECTALL, &CAffinityDlg::OnBnClickedSelectall)
|
|
ON_BN_CLICKED(IDC_UNSELECTALL, &CAffinityDlg::OnBnClickedUnselectall)
|
|
END_MESSAGE_MAP()
|
|
|
|
|
|
// CAffinityDlg message handlers
|
|
|
|
|
|
BOOL CAffinityDlg::OnInitDialog() {
|
|
|
|
SetWindowText(m_Title);
|
|
|
|
CRect rc;
|
|
GetDlgItem(IDC_DUMMY)->GetClientRect(&rc);
|
|
int cpus = CGlobals::GetProcessorCount();
|
|
|
|
DWORD_PTR processAffinity, systemAffinity;
|
|
BOOL validAffinity = FALSE;
|
|
|
|
if(m_Affinity && m_Process)
|
|
validAffinity = ::GetProcessAffinityMask(::GetCurrentProcess(), &processAffinity, &systemAffinity);
|
|
|
|
CString name;
|
|
int row = cpus > 32 ? 8 : 4;
|
|
auto font = GetFont();
|
|
for(int i = 0; i < cpus; i++) {
|
|
name.Format(L"CPU %d", i);
|
|
m_Buttons[i].Create(name, WS_CHILD | WS_VISIBLE | (m_Affinity ? BS_AUTOCHECKBOX : BS_AUTORADIOBUTTON | (i == 0 ? WS_GROUP : 0) | WS_TABSTOP),
|
|
CRect(CPoint(10 + (rc.Width() + 10) * (i % row), 20 + (rc.Height() + 10) * (i / row)), CSize(rc.Width(), rc.Height())),
|
|
this, IDC_FIRST + i);
|
|
if(m_Affinity && m_pThread == nullptr)
|
|
CheckDlgButton(IDC_FIRST + i, (validAffinity && processAffinity & (1i64 << i)) == 0 ? BST_UNCHECKED : BST_CHECKED);
|
|
m_Buttons[i].SetFont(font);
|
|
}
|
|
|
|
if(cpus > 16) {
|
|
CRect rcButton, rcWindow;
|
|
GetDlgItem(IDOK)->GetClientRect(&rcButton);
|
|
GetWindowRect(&rcWindow);
|
|
int sizex = row == 4 ? rcWindow.Width() : (rcWindow.Width() - rcButton.Width()) * 2 + rcButton.Width();
|
|
if(row > 4) {
|
|
int x1 = sizex / 2 - rcButton.Width() - 20;
|
|
int x2 = sizex / 2 + 20;
|
|
CRect rcButton2;
|
|
GetDlgItem(IDOK)->GetWindowRect(&rcButton2);
|
|
ScreenToClient(&rcButton2);
|
|
GetDlgItem(IDOK)->MoveWindow(x1, rcButton2.top, rcButton.Width(), rcButton.Height());
|
|
GetDlgItem(IDCANCEL)->MoveWindow(x2, rcButton2.top, rcButton.Width(), rcButton.Height());
|
|
|
|
GetDlgItem(IDC_SELECTALL)->MoveWindow(sizex - rcButton.Width() - 30, 20, rcButton.Width(), rcButton.Height());
|
|
GetDlgItem(IDC_UNSELECTALL)->MoveWindow(sizex - rcButton.Width() - 30, 30 + rcButton.Height(), rcButton.Width(), rcButton.Height());
|
|
}
|
|
SetWindowPos(nullptr, 0, 0, sizex, rcWindow.Height(), SWP_NOMOVE | SWP_NOZORDER);
|
|
}
|
|
|
|
if(!m_Affinity) {
|
|
GetDlgItem(IDC_SELECTALL)->ShowWindow(SW_HIDE);
|
|
GetDlgItem(IDC_UNSELECTALL)->ShowWindow(SW_HIDE);
|
|
}
|
|
|
|
if(m_Affinity && m_pThread) {
|
|
auto affinity = m_pThread->GetAffinity();
|
|
int i = 0;
|
|
while(affinity) {
|
|
if(affinity & 1)
|
|
CheckDlgButton(IDC_FIRST + i, BST_CHECKED);
|
|
affinity >>= 1;
|
|
i++;
|
|
}
|
|
}
|
|
if(m_Affinity && !m_Process)
|
|
DisableNonProcessAffinity();
|
|
|
|
if(!m_Affinity) {
|
|
m_IdealCPU = m_pThread ? m_pThread->GetIdealCPU() : 0;
|
|
}
|
|
CDialogEx::OnInitDialog();
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CAffinityDlg::DisableNonProcessAffinity() {
|
|
DWORD_PTR processAffinity, systemAffinity;
|
|
if(!::GetProcessAffinityMask(::GetCurrentProcess(), &processAffinity, &systemAffinity))
|
|
return;
|
|
|
|
if(processAffinity == systemAffinity)
|
|
return;
|
|
|
|
// disable CPUs that are not part of the process affinity mask
|
|
int n = 0;
|
|
while(processAffinity) {
|
|
if((processAffinity & 1) == 0) {
|
|
CheckDlgButton(IDC_FIRST + n, BST_UNCHECKED);
|
|
m_Buttons[n].EnableWindow(FALSE);
|
|
}
|
|
processAffinity >>= 1;
|
|
++n;
|
|
}
|
|
}
|
|
|
|
DWORD_PTR CAffinityDlg::CalcAffinity() {
|
|
DWORD_PTR affinity = 0;
|
|
for(int i = 0; i < CGlobals::GetProcessorCount(); i++)
|
|
if(m_Buttons[i].GetCheck() == BST_CHECKED)
|
|
affinity |= (DWORD_PTR)1 << i;
|
|
return affinity;
|
|
}
|
|
|
|
void CAffinityDlg::OnOK() {
|
|
UpdateData();
|
|
|
|
if(m_Affinity) {
|
|
auto affinity = CalcAffinity();
|
|
if(affinity == 0) {
|
|
AfxMessageBox(L"Affinity of zero is not allowed");
|
|
return;
|
|
}
|
|
m_SelectedAfinity = affinity;
|
|
}
|
|
EndDialog(IDOK);
|
|
}
|
|
|
|
void CAffinityDlg::OnBnClickedSelectall() {
|
|
for(int i = 0; i < CGlobals::GetProcessorCount(); i++)
|
|
CheckDlgButton(IDC_FIRST + i, BST_CHECKED);
|
|
}
|
|
|
|
void CAffinityDlg::OnBnClickedUnselectall() {
|
|
for(int i = 0; i < CGlobals::GetProcessorCount(); i++)
|
|
CheckDlgButton(IDC_FIRST + i, BST_UNCHECKED);
|
|
}
|