Moved the CPU detection code into the MUtils library.

This commit is contained in:
LoRd_MuldeR 2014-11-25 03:15:03 +01:00
parent 035699c84e
commit 52142c6e6b
8 changed files with 32 additions and 273 deletions

View File

@ -35,7 +35,7 @@
#define VER_LAMEXP_MINOR_LO 1 #define VER_LAMEXP_MINOR_LO 1
#define VER_LAMEXP_TYPE Beta #define VER_LAMEXP_TYPE Beta
#define VER_LAMEXP_PATCH 1 #define VER_LAMEXP_PATCH 1
#define VER_LAMEXP_BUILD 1590 #define VER_LAMEXP_BUILD 1591
#define VER_LAMEXP_CONFG 1558 #define VER_LAMEXP_CONFG 1558
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////

View File

@ -1610,7 +1610,7 @@ void MainWindow::encodeButtonClicked(void)
switch(QMessageBox::warning(this, tr("Low Diskspace Warning"), lowDiskspaceMsg, tr("Abort Encoding Process"), tr("Clean Disk Now"), tr("Ignore"))) switch(QMessageBox::warning(this, tr("Low Diskspace Warning"), lowDiskspaceMsg, tr("Abort Encoding Process"), tr("Clean Disk Now"), tr("Ignore")))
{ {
case 1: case 1:
QProcess::startDetached(QString("%1/cleanmgr.exe").arg(lamexp_known_folder(lamexp_folder_systemfolder)), QStringList() << "/D" << tempFolderParts.first()); QProcess::startDetached(QString("%1/cleanmgr.exe").arg(MUtils::OS::known_folder(MUtils::OS::FOLDER_SYSTEMFOLDER)), QStringList() << "/D" << tempFolderParts.first());
case 0: case 0:
return; return;
break; break;
@ -2483,7 +2483,7 @@ void MainWindow::findFileContextActionTriggered(void)
{ {
QString systemRootPath; QString systemRootPath;
QDir systemRoot(lamexp_known_folder(lamexp_folder_systemfolder)); QDir systemRoot(MUtils::OS::known_folder(MUtils::OS::FOLDER_SYSTEMFOLDER));
if(systemRoot.exists() && systemRoot.cdUp()) if(systemRoot.exists() && systemRoot.cdUp())
{ {
systemRootPath = systemRoot.canonicalPath(); systemRootPath = systemRoot.canonicalPath();

View File

@ -45,6 +45,8 @@
//MUtils //MUtils
#include <MUtils/Global.h> #include <MUtils/Global.h>
#include <MUtils/OSSupport.h>
#include <MUtils/CPUFeatures.h>
//Qt //Qt
#include <QApplication> #include <QApplication>
@ -542,8 +544,8 @@ void ProcessingDialog::initEncoding(void)
unsigned int maximumInstances = qBound(0U, m_settings->maximumInstances(), MAX_INSTANCES); unsigned int maximumInstances = qBound(0U, m_settings->maximumInstances(), MAX_INSTANCES);
if(maximumInstances < 1) if(maximumInstances < 1)
{ {
lamexp_cpu_t cpuFeatures = lamexp_detect_cpu_features(lamexp_arguments()); const MUtils::CPUFetaures::cpu_info_t cpuFeatures = MUtils::CPUFetaures::detect(lamexp_arguments());
maximumInstances = cores2instances(qBound(1, cpuFeatures.count, 64)); maximumInstances = cores2instances(qBound(1U, cpuFeatures.count, 64U));
} }
maximumInstances = qBound(1U, maximumInstances, static_cast<unsigned int>(m_pendingJobs.count())); maximumInstances = qBound(1U, maximumInstances, static_cast<unsigned int>(m_pendingJobs.count()));
@ -890,7 +892,7 @@ void ProcessingDialog::contextMenuShowFileActionTriggered(void)
{ {
QString systemRootPath; QString systemRootPath;
QDir systemRoot(lamexp_known_folder(lamexp_folder_systemfolder)); QDir systemRoot(MUtils::OS::known_folder(MUtils::OS::FOLDER_SYSTEMFOLDER));
if(systemRoot.exists() && systemRoot.cdUp()) if(systemRoot.exists() && systemRoot.cdUp())
{ {
systemRootPath = systemRoot.canonicalPath(); systemRootPath = systemRoot.canonicalPath();

View File

@ -45,35 +45,6 @@ extern const char* LAMEXP_DEFAULT_TRANSLATION;
// TYPE DEFINITIONS // TYPE DEFINITIONS
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
//CPU features
typedef struct
{
int family;
int model;
int stepping;
int count;
bool x64;
bool mmx;
bool sse;
bool sse2;
bool sse3;
bool ssse3;
char vendor[0x40];
char brand[0x40];
bool intel;
}
lamexp_cpu_t;
//Known folders
typedef enum
{
lamexp_folder_localappdata = 0,
lamexp_folder_programfiles = 2,
lamexp_folder_systemfolder = 3,
lamexp_folder_systroot_dir = 4
}
lamexp_known_folder_t;
//LameXP user-defined events //LameXP user-defined events
typedef enum typedef enum
{ {
@ -166,7 +137,6 @@ const QString lamexp_clean_filepath(const QString &str);
unsigned __int64 lamexp_current_file_time(void); unsigned __int64 lamexp_current_file_time(void);
void lamexp_dbg_dbg_output_string(const char* format, ...); void lamexp_dbg_dbg_output_string(const char* format, ...);
unsigned long lamexp_dbg_private_bytes(void); unsigned long lamexp_dbg_private_bytes(void);
lamexp_cpu_t lamexp_detect_cpu_features(const QStringList &argv);
bool lamexp_detect_wine(void); bool lamexp_detect_wine(void);
bool lamexp_enable_close_button(const QWidget *win, const bool bEnable = true); bool lamexp_enable_close_button(const QWidget *win, const bool bEnable = true);
bool lamexp_exec_shell(const QWidget *win, const QString &url, const bool explore = false); bool lamexp_exec_shell(const QWidget *win, const QString &url, const bool explore = false);
@ -187,7 +157,6 @@ void lamexp_ipc_read(unsigned int *command, char* message, size_t buffSize);
void lamexp_ipc_send(unsigned int command, const char* message); void lamexp_ipc_send(unsigned int command, const char* message);
bool lamexp_is_executable(const QString &path); bool lamexp_is_executable(const QString &path);
bool lamexp_is_hibernation_supported(void); bool lamexp_is_hibernation_supported(void);
const QString &lamexp_known_folder(lamexp_known_folder_t folder_id);
const QString lamexp_lookup_tool(const QString &toolName); const QString lamexp_lookup_tool(const QString &toolName);
void lamexp_message_handler(QtMsgType type, const char *msg); void lamexp_message_handler(QtMsgType type, const char *msg);
const char *lamexp_mulders_url(void); const char *lamexp_mulders_url(void);

View File

@ -69,6 +69,7 @@
//MUtils //MUtils
#include <MUtils/Global.h> #include <MUtils/Global.h>
#include <MUtils/OSSupport.h>
//CRT includes //CRT includes
#include <cstdio> #include <cstdio>
@ -793,113 +794,6 @@ void lamexp_init_console(const QStringList &argv)
} }
} }
/*
* Detect CPU features
*/
lamexp_cpu_t lamexp_detect_cpu_features(const QStringList &argv)
{
typedef BOOL (WINAPI *IsWow64ProcessFun)(__in HANDLE hProcess, __out PBOOL Wow64Process);
lamexp_cpu_t features;
SYSTEM_INFO systemInfo;
int CPUInfo[4] = {-1};
char CPUIdentificationString[0x40];
char CPUBrandString[0x40];
memset(&features, 0, sizeof(lamexp_cpu_t));
memset(&systemInfo, 0, sizeof(SYSTEM_INFO));
memset(CPUIdentificationString, 0, sizeof(CPUIdentificationString));
memset(CPUBrandString, 0, sizeof(CPUBrandString));
__cpuid(CPUInfo, 0);
memcpy(CPUIdentificationString, &CPUInfo[1], sizeof(int));
memcpy(CPUIdentificationString + 4, &CPUInfo[3], sizeof(int));
memcpy(CPUIdentificationString + 8, &CPUInfo[2], sizeof(int));
features.intel = (_stricmp(CPUIdentificationString, "GenuineIntel") == 0);
strncpy_s(features.vendor, 0x40, CPUIdentificationString, _TRUNCATE);
if(CPUInfo[0] >= 1)
{
__cpuid(CPUInfo, 1);
features.mmx = (CPUInfo[3] & 0x800000) || false;
features.sse = (CPUInfo[3] & 0x2000000) || false;
features.sse2 = (CPUInfo[3] & 0x4000000) || false;
features.ssse3 = (CPUInfo[2] & 0x200) || false;
features.sse3 = (CPUInfo[2] & 0x1) || false;
features.ssse3 = (CPUInfo[2] & 0x200) || false;
features.stepping = CPUInfo[0] & 0xf;
features.model = ((CPUInfo[0] >> 4) & 0xf) + (((CPUInfo[0] >> 16) & 0xf) << 4);
features.family = ((CPUInfo[0] >> 8) & 0xf) + ((CPUInfo[0] >> 20) & 0xff);
}
__cpuid(CPUInfo, 0x80000000);
int nExIds = qMax<int>(qMin<int>(CPUInfo[0], 0x80000004), 0x80000000);
for(int i = 0x80000002; i <= nExIds; ++i)
{
__cpuid(CPUInfo, i);
switch(i)
{
case 0x80000002:
memcpy(CPUBrandString, CPUInfo, sizeof(CPUInfo));
break;
case 0x80000003:
memcpy(CPUBrandString + 16, CPUInfo, sizeof(CPUInfo));
break;
case 0x80000004:
memcpy(CPUBrandString + 32, CPUInfo, sizeof(CPUInfo));
break;
}
}
strncpy_s(features.brand, 0x40, CPUBrandString, _TRUNCATE);
if(strlen(features.brand) < 1) strncpy_s(features.brand, 0x40, "Unknown", _TRUNCATE);
if(strlen(features.vendor) < 1) strncpy_s(features.vendor, 0x40, "Unknown", _TRUNCATE);
#if (!(defined(_M_X64) || defined(_M_IA64)))
QLibrary Kernel32Lib("kernel32.dll");
if(IsWow64ProcessFun IsWow64ProcessPtr = (IsWow64ProcessFun) Kernel32Lib.resolve("IsWow64Process"))
{
BOOL x64flag = FALSE;
if(IsWow64ProcessPtr(GetCurrentProcess(), &x64flag))
{
features.x64 = (x64flag == TRUE);
}
}
#else
features.x64 = true;
#endif
DWORD_PTR procAffinity, sysAffinity;
if(GetProcessAffinityMask(GetCurrentProcess(), &procAffinity, &sysAffinity))
{
for(DWORD_PTR mask = 1; mask; mask <<= 1)
{
features.count += ((sysAffinity & mask) ? (1) : (0));
}
}
if(features.count < 1)
{
GetNativeSystemInfo(&systemInfo);
features.count = qBound(1UL, systemInfo.dwNumberOfProcessors, 64UL);
}
if(argv.count() > 0)
{
bool flag = false;
for(int i = 0; i < argv.count(); i++)
{
if(!argv[i].compare("--force-cpu-no-64bit", Qt::CaseInsensitive)) { flag = true; features.x64 = false; }
if(!argv[i].compare("--force-cpu-no-sse", Qt::CaseInsensitive)) { flag = true; features.sse = features.sse2 = features.sse3 = features.ssse3 = false; }
if(!argv[i].compare("--force-cpu-no-intel", Qt::CaseInsensitive)) { flag = true; features.intel = false; }
}
if(flag) qWarning("CPU flags overwritten by user-defined parameters. Take care!\n");
}
return features;
}
/* /*
* Check for debugger (detect routine) * Check for debugger (detect routine)
*/ */
@ -1273,116 +1167,6 @@ const QStringList &lamexp_arguments(void)
return (*g_lamexp_argv.list); return (*g_lamexp_argv.list);
} }
/*
* Locate known folder on local system
*/
const QString &lamexp_known_folder(lamexp_known_folder_t folder_id)
{
static const int CSIDL_FLAG_CREATE = 0x8000;
typedef enum { KF_FLAG_CREATE = 0x00008000 } kf_flags_t;
struct
{
const int csidl;
const GUID guid;
}
static s_folders[] =
{
{ 0x001c, {0xF1B32785,0x6FBA,0x4FCF,{0x9D,0x55,0x7B,0x8E,0x7F,0x15,0x70,0x91}} }, //CSIDL_LOCAL_APPDATA
{ 0x0026, {0x905e63b6,0xc1bf,0x494e,{0xb2,0x9c,0x65,0xb7,0x32,0xd3,0xd2,0x1a}} }, //CSIDL_PROGRAM_FILES
{ 0x0024, {0xF38BF404,0x1D43,0x42F2,{0x93,0x05,0x67,0xDE,0x0B,0x28,0xFC,0x23}} }, //CSIDL_WINDOWS_FOLDER
{ 0x0025, {0x1AC14E77,0x02E7,0x4E5D,{0xB7,0x44,0x2E,0xB1,0xAE,0x51,0x98,0xB7}} }, //CSIDL_SYSTEM_FOLDER
};
size_t folderId = size_t(-1);
switch(folder_id)
{
case lamexp_folder_localappdata: folderId = 0; break;
case lamexp_folder_programfiles: folderId = 1; break;
case lamexp_folder_systroot_dir: folderId = 2; break;
case lamexp_folder_systemfolder: folderId = 3; break;
}
if(folderId == size_t(-1))
{
qWarning("Invalid 'known' folder was requested!");
return *reinterpret_cast<QString*>(NULL);
}
QReadLocker readLock(&g_lamexp_known_folder.lock);
//Already in cache?
if(g_lamexp_known_folder.knownFolders)
{
if(g_lamexp_known_folder.knownFolders->contains(folderId))
{
return (*g_lamexp_known_folder.knownFolders)[folderId];
}
}
//Obtain write lock to initialize
readLock.unlock();
QWriteLocker writeLock(&g_lamexp_known_folder.lock);
//Still not in cache?
if(g_lamexp_known_folder.knownFolders)
{
if(g_lamexp_known_folder.knownFolders->contains(folderId))
{
return (*g_lamexp_known_folder.knownFolders)[folderId];
}
}
//Initialize on first call
if(!g_lamexp_known_folder.knownFolders)
{
QLibrary shell32("shell32.dll");
if(shell32.load())
{
g_lamexp_known_folder.getFolderPath = (SHGetFolderPath_t) shell32.resolve("SHGetFolderPathW");
g_lamexp_known_folder.getKnownFolderPath = (SHGetKnownFolderPath_t) shell32.resolve("SHGetKnownFolderPath");
}
g_lamexp_known_folder.knownFolders = new QMap<size_t, QString>();
}
QString folderPath;
//Now try to get the folder path!
if(g_lamexp_known_folder.getKnownFolderPath)
{
WCHAR *path = NULL;
if(g_lamexp_known_folder.getKnownFolderPath(s_folders[folderId].guid, KF_FLAG_CREATE, NULL, &path) == S_OK)
{
//MessageBoxW(0, path, L"SHGetKnownFolderPath", MB_TOPMOST);
QDir folderTemp = QDir(QDir::fromNativeSeparators(QString::fromUtf16(reinterpret_cast<const unsigned short*>(path))));
if(folderTemp.exists())
{
folderPath = folderTemp.canonicalPath();
}
CoTaskMemFree(path);
}
}
else if(g_lamexp_known_folder.getFolderPath)
{
WCHAR *path = new WCHAR[4096];
if(g_lamexp_known_folder.getFolderPath(NULL, s_folders[folderId].csidl | CSIDL_FLAG_CREATE, NULL, NULL, path) == S_OK)
{
//MessageBoxW(0, path, L"SHGetFolderPathW", MB_TOPMOST);
QDir folderTemp = QDir(QDir::fromNativeSeparators(QString::fromUtf16(reinterpret_cast<const unsigned short*>(path))));
if(folderTemp.exists())
{
folderPath = folderTemp.canonicalPath();
}
}
MUTILS_DELETE_ARRAY(path);
}
//Update cache
g_lamexp_known_folder.knownFolders->insert(folderId, folderPath);
return (*g_lamexp_known_folder.knownFolders)[folderId];
}
/* /*
* Check if visual themes are enabled (WinXP and later) * Check if visual themes are enabled (WinXP and later)
*/ */
@ -1406,7 +1190,7 @@ bool lamexp_themes_enabled(void)
if(osVersion >= lamexp_winver_winxp) if(osVersion >= lamexp_winver_winxp)
{ {
IsAppThemedFun IsAppThemedPtr = NULL; IsAppThemedFun IsAppThemedPtr = NULL;
QLibrary uxTheme(QString("%1/UxTheme.dll").arg(lamexp_known_folder(lamexp_folder_systemfolder))); QLibrary uxTheme(QString("%1/UxTheme.dll").arg(MUtils::OS::known_folder(MUtils::OS::FOLDER_SYSTEMFOLDER)));
if(uxTheme.load()) if(uxTheme.load())
{ {
IsAppThemedPtr = (IsAppThemedFun) uxTheme.resolve("IsAppThemed"); IsAppThemedPtr = (IsAppThemedFun) uxTheme.resolve("IsAppThemed");
@ -1598,7 +1382,7 @@ bool lamexp_play_sound_file(const QString &library, const unsigned short uiSound
QFileInfo libraryFile(library); QFileInfo libraryFile(library);
if(!libraryFile.isAbsolute()) if(!libraryFile.isAbsolute())
{ {
const QString &systemDir = lamexp_known_folder(lamexp_folder_systemfolder); const QString &systemDir = MUtils::OS::known_folder(MUtils::OS::FOLDER_SYSTEMFOLDER);
if(!systemDir.isEmpty()) if(!systemDir.isEmpty())
{ {
libraryFile.setFile(QDir(systemDir), libraryFile.fileName()); libraryFile.setFile(QDir(systemDir), libraryFile.fileName());

View File

@ -37,6 +37,7 @@
#include <MUtils/Global.h> #include <MUtils/Global.h>
#include <MUtils/OSSupport.h> #include <MUtils/OSSupport.h>
#include <MUtils/Version.h> #include <MUtils/Version.h>
#include <MUtils/CPUFeatures.h>
//Qt includes //Qt includes
#include <QApplication> #include <QApplication>
@ -88,11 +89,11 @@ static int lamexp_main(int argc, char* argv[])
qDebug(""); qDebug("");
//Detect CPU capabilities //Detect CPU capabilities
lamexp_cpu_t cpuFeatures = lamexp_detect_cpu_features(arguments); const MUtils::CPUFetaures::cpu_info_t cpuFeatures = MUtils::CPUFetaures::detect(lamexp_arguments());
qDebug(" CPU vendor id : %s (Intel: %s)", cpuFeatures.vendor, MUTILS_BOOL2STR(cpuFeatures.intel)); qDebug(" CPU vendor id : %s (Intel=%s)", cpuFeatures.vendor, MUTILS_BOOL2STR(cpuFeatures.intel));
qDebug("CPU brand string : %s", cpuFeatures.brand); qDebug("CPU brand string : %s", cpuFeatures.brand);
qDebug(" CPU signature : Family: %d, Model: %d, Stepping: %d", cpuFeatures.family, cpuFeatures.model, cpuFeatures.stepping); qDebug(" CPU signature : Family=%d Model=%d Stepping=%d", cpuFeatures.family, cpuFeatures.model, cpuFeatures.stepping);
qDebug("CPU capabilities : MMX: %s, SSE: %s, SSE2: %s, SSE3: %s, SSSE3: %s, x64: %s", MUTILS_BOOL2STR(cpuFeatures.mmx), MUTILS_BOOL2STR(cpuFeatures.sse), MUTILS_BOOL2STR(cpuFeatures.sse2), MUTILS_BOOL2STR(cpuFeatures.sse3), MUTILS_BOOL2STR(cpuFeatures.ssse3), MUTILS_BOOL2STR(cpuFeatures.x64)); qDebug("CPU capabilities : MMX=%s SSE=%s SSE2=%s SSE3=%s SSSE3=%s SSE4=%s SSE4.2=%s x64=%s", MUTILS_BOOL2STR(cpuFeatures.features & MUtils::CPUFetaures::FLAG_MMX), MUTILS_BOOL2STR(cpuFeatures.features & MUtils::CPUFetaures::FLAG_SSE), MUTILS_BOOL2STR(cpuFeatures.features & MUtils::CPUFetaures::FLAG_SSE2), MUTILS_BOOL2STR(cpuFeatures.features & MUtils::CPUFetaures::FLAG_SSE3), MUTILS_BOOL2STR(cpuFeatures.features & MUtils::CPUFetaures::FLAG_SSSE3), MUTILS_BOOL2STR(cpuFeatures.features & MUtils::CPUFetaures::FLAG_SSE4), MUTILS_BOOL2STR(cpuFeatures.features & MUtils::CPUFetaures::FLAG_SSE42), MUTILS_BOOL2STR(cpuFeatures.x64));
qDebug(" Number of CPU's : %d\n", cpuFeatures.count); qDebug(" Number of CPU's : %d\n", cpuFeatures.count);
//Initialize Qt //Initialize Qt
@ -158,7 +159,7 @@ static int lamexp_main(int argc, char* argv[])
SettingsModel *settingsModel = new SettingsModel(); SettingsModel *settingsModel = new SettingsModel();
//Show splash screen //Show splash screen
InitializationThread *poInitializationThread = new InitializationThread(&cpuFeatures); InitializationThread *poInitializationThread = new InitializationThread(cpuFeatures);
SplashScreen::showSplash(poInitializationThread); SplashScreen::showSplash(poInitializationThread);
settingsModel->slowStartup(poInitializationThread->getSlowIndicator()); settingsModel->slowStartup(poInitializationThread->getSlowIndicator());
MUTILS_DELETE(poInitializationThread); MUTILS_DELETE(poInitializationThread);

View File

@ -207,16 +207,13 @@ volatile bool ExtractorTask::s_bCustom = false;
// Constructor // Constructor
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
InitializationThread::InitializationThread(const lamexp_cpu_t *cpuFeatures) InitializationThread::InitializationThread(const MUtils::CPUFetaures::cpu_info_t &cpuFeatures)
:
m_bSuccess(false),
m_slowIndicator(false)
{ {
m_bSuccess = false;
memset(&m_cpuFeatures, 0, sizeof(lamexp_cpu_t));
m_slowIndicator = false;
if(cpuFeatures) memcpy(&m_cpuFeatures, &cpuFeatures, sizeof(MUtils::CPUFetaures::cpu_info_t));
{
memcpy(&m_cpuFeatures, cpuFeatures, sizeof(lamexp_cpu_t));
}
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@ -254,7 +251,7 @@ double InitializationThread::doInit(const size_t threadCount)
//CPU type selection //CPU type selection
unsigned int cpuSupport = 0; unsigned int cpuSupport = 0;
if(m_cpuFeatures.sse && m_cpuFeatures.sse2 && m_cpuFeatures.intel) if((m_cpuFeatures.features & MUtils::CPUFetaures::FLAG_SSE) && (m_cpuFeatures.features & MUtils::CPUFetaures::FLAG_SSE2) && m_cpuFeatures.intel)
{ {
cpuSupport = m_cpuFeatures.x64 ? CPU_TYPE_X64_SSE : CPU_TYPE_X86_SSE; cpuSupport = m_cpuFeatures.x64 ? CPU_TYPE_X64_SSE : CPU_TYPE_X86_SSE;
} }

View File

@ -22,7 +22,13 @@
#pragma once #pragma once
//Internal
#include "Global.h" #include "Global.h"
//MUtils
#include <MUtils/CPUFeatures.h>
//Qt
#include <QThread> #include <QThread>
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@ -34,7 +40,7 @@ class InitializationThread: public QThread
Q_OBJECT Q_OBJECT
public: public:
InitializationThread(const lamexp_cpu_t *cpuFeatures); InitializationThread(const MUtils::CPUFetaures::cpu_info_t &cpuFeatures);
bool getSuccess(void) { return !isRunning() && m_bSuccess; } bool getSuccess(void) { return !isRunning() && m_bSuccess; }
bool getSlowIndicator(void) { return m_slowIndicator; } bool getSlowIndicator(void) { return m_slowIndicator; }
@ -54,6 +60,6 @@ private:
void initQAac(void); void initQAac(void);
bool m_bSuccess; bool m_bSuccess;
lamexp_cpu_t m_cpuFeatures; MUtils::CPUFetaures::cpu_info_t m_cpuFeatures;
bool m_slowIndicator; bool m_slowIndicator;
}; };