@@ -348,7 +348,7 @@ struct VM {
348348 UPTIME,
349349 ODD_CPU_THREADS,
350350 INTEL_THREAD_MISMATCH,
351- INTEL_XEON_THREAD_MISMATCH ,
351+ XEON_THREAD_MISMATCH ,
352352 EXTREME,
353353 NO_MEMO,
354354 WIN_HYPERV_DEFAULT,
@@ -589,20 +589,22 @@ struct VM {
589589#endif
590590 }
591591
592- [[nodiscard]] static std::string get_model () {
592+ struct model_struct {
593+ bool found;
594+ bool is_xeon;
595+ bool is_i_series;
596+ std::string string;
597+ };
598+
599+ [[nodiscard]] static model_struct get_model () {
593600 const std::string brand = get_brand ();
594601
595602 constexpr const char * intel_i_series_regex = " i[0-9]-[A-Z0-9]{1,7}" ;
596603 constexpr const char * intel_xeon_series_regex = " [DEW]-[A-Z0-9]{1,7}" ;
597604
598- constexpr std::array<const char *, 2 > regex_templates {{
599- intel_i_series_regex,
600- intel_xeon_series_regex
601- }};
602-
603605 std::string match_str = " " ;
604606
605- for (const auto regex : regex_templates) {
607+ auto match = [&] (const char * regex) -> bool {
606608 std::regex pattern (regex);
607609
608610 auto words_begin = std::sregex_iterator (brand.begin (), brand.end (), pattern);
@@ -614,11 +616,32 @@ struct VM {
614616 }
615617
616618 if (!match_str.empty ()) {
617- return match_str;
619+ return true ;
620+ }
621+
622+ return false ;
623+ };
624+
625+ bool found = false ;
626+ bool is_xeon = false ;
627+ bool is_i_series = false ;
628+ std::string string = " " ;
629+
630+ if (cpu::is_intel ()) {
631+ if (match (intel_i_series_regex)) {
632+ found = true ;
633+ is_i_series = true ;
634+ string = match_str;
635+ } else if (match (intel_xeon_series_regex)) {
636+ found = true ;
637+ is_xeon = true ;
638+ string = match_str;
618639 }
619640 }
620641
621- return " " ;
642+ // no AMD (for now)
643+
644+ return model_struct{ found, is_xeon, is_i_series, string };
622645 };
623646
624647#if (CPP >= 17)
@@ -4901,7 +4924,6 @@ struct VM {
49014924 IDTR idtrStruct;
49024925 __sidt (&idtrStruct);
49034926 std::memcpy (idtr, &idtrStruct, sizeof (IDTR));
4904- */
49054927 #else
49064928 return false ;
49074929 #endif
@@ -5877,7 +5899,7 @@ struct VM {
58775899 /* *
58785900 * @brief Check for CPUs that don't match their thread count
58795901 * @category All, x86
5880- * @links https://en.wikipedia.org/wiki/List_of_Intel_Core_processors
5902+ * @link https://en.wikipedia.org/wiki/List_of_Intel_Core_processors
58815903 */
58825904 [[nodiscard]] static bool intel_thread_mismatch () try {
58835905 if (core::disabled (INTEL_THREAD_MISMATCH)) {
@@ -5891,15 +5913,19 @@ struct VM {
58915913 return false ;
58925914 }
58935915
5894- const std::string model = cpu::get_model ();
5916+ const cpu::model_struct model = cpu::get_model ();
58955917
5896- debug (" INTEL_THREAD_MISMATCH: CPU model = " , model);
5918+ if (!model.found ) {
5919+ return false ;
5920+ }
58975921
5898- if (model.empty () ) {
5922+ if (! model.is_i_series ) {
58995923 return false ;
59005924 }
59015925
5902- std::unordered_map<std::string, u8 > thread_database = {
5926+ debug (" INTEL_THREAD_MISMATCH: CPU model = " , model.string );
5927+
5928+ const std::unordered_map<std::string, u8 > thread_database = {
59035929 // i3 series
59045930 { " i3-1000G1" , 4 },
59055931 { " i3-1000G4" , 4 },
@@ -6856,11 +6882,11 @@ struct VM {
68566882 };
68576883
68586884 // basically means "if there's 0 matches in the database, return false"
6859- if (thread_database.count (model) == 0 ) {
6885+ if (thread_database.count (model. string ) == 0 ) {
68606886 return false ;
68616887 }
68626888
6863- const u8 threads = thread_database.at (model);
6889+ const u8 threads = thread_database.at (model. string );
68646890
68656891 debug (" INTEL_THREAD_MISMATCH: thread in database = " , static_cast <u32 >(threads));
68666892
@@ -6873,6 +6899,158 @@ struct VM {
68736899 }
68746900
68756901
6902+ /* *
6903+ * @brief Check for Intel Xeon CPUs that don't match their thread count
6904+ * @category All, x86
6905+ * @link https://en.wikipedia.org/wiki/List_of_Intel_Core_processors
6906+ */
6907+ [[nodiscard]] static bool xeon_thread_mismatch () try {
6908+ if (core::disabled (XEON_THREAD_MISMATCH)) {
6909+ return false ;
6910+ }
6911+
6912+ #if (!x86)
6913+ return false ;
6914+ #else
6915+ if (!cpu::is_intel ()) {
6916+ return false ;
6917+ }
6918+
6919+ const cpu::model_struct model = cpu::get_model ();
6920+
6921+ if (!model.found ) {
6922+ return false ;
6923+ }
6924+
6925+ if (!model.is_i_series ) {
6926+ return false ;
6927+ }
6928+
6929+ debug (" XEON_THREAD_MISMATCH: CPU model = " , model.string );
6930+
6931+ const std::unordered_map<std::string, u8 > xeon_thread_database = {
6932+ // Xeon D
6933+ { " D-1518" , 8 },
6934+ { " D-1520" , 8 },
6935+ { " D-1521" , 8 },
6936+ { " D-1527" , 8 },
6937+ { " D-1528" , 12 },
6938+ { " D-1529" , 8 },
6939+ { " D-1531" , 12 },
6940+ { " D-1537" , 16 },
6941+ { " D-1539" , 16 },
6942+ { " D-1540" , 16 },
6943+ { " D-1541" , 16 },
6944+ { " D-1548" , 16 },
6945+ { " D-1557" , 24 },
6946+ { " D-1559" , 24 },
6947+ { " D-1567" , 24 },
6948+ { " D-1571" , 32 },
6949+ { " D-1577" , 32 },
6950+ { " D-1581" , 32 },
6951+ { " D-1587" , 32 },
6952+ { " D-1513N" , 8 },
6953+ { " D-1523N" , 8 },
6954+ { " D-1533N" , 12 },
6955+ { " D-1543N" , 16 },
6956+ { " D-1553N" , 16 },
6957+ { " D-1602" , 4 },
6958+ { " D-1612" , 8 },
6959+ { " D-1622" , 8 },
6960+ { " D-1627" , 8 },
6961+ { " D-1632" , 16 },
6962+ { " D-1637" , 12 },
6963+ { " D-1623N" , 8 },
6964+ { " D-1633N" , 12 },
6965+ { " D-1649N" , 16 },
6966+ { " D-1653N" , 16 },
6967+ { " D-2141I" , 16 },
6968+ { " D-2161I" , 24 },
6969+ { " D-2191" , 36 },
6970+ { " D-2123IT" , 8 },
6971+ { " D-2142IT" , 16 },
6972+ { " D-2143IT" , 16 },
6973+ { " D-2163IT" , 24 },
6974+ { " D-2173IT" , 28 },
6975+ { " D-2183IT" , 32 },
6976+ { " D-2145NT" , 16 },
6977+ { " D-2146NT" , 16 },
6978+ { " D-2166NT" , 24 },
6979+ { " D-2177NT" , 28 },
6980+ { " D-2187NT" , 32 },
6981+
6982+ // Xeon E
6983+ { " E-2104G" , 4 },
6984+ { " E-2124" , 4 },
6985+ { " E-2124G" , 4 },
6986+ { " E-2126G" , 6 },
6987+ { " E-2134" , 8 },
6988+ { " E-2136" , 12 },
6989+ { " E-2144G" , 8 },
6990+ { " E-2146G" , 12 },
6991+ { " E-2174G" , 8 },
6992+ { " E-2176G" , 12 },
6993+ { " E-2186G" , 12 },
6994+ { " E-2176M" , 12 },
6995+ { " E-2186M" , 12 },
6996+ { " E-2224" , 4 },
6997+ { " E-2224G" , 4 },
6998+ { " E-2226G" , 6 },
6999+ { " E-2234" , 8 },
7000+ { " E-2236" , 12 },
7001+ { " E-2244G" , 8 },
7002+ { " E-2246G" , 12 },
7003+ { " E-2274G" , 8 },
7004+ { " E-2276G" , 12 },
7005+ { " E-2278G" , 16 },
7006+ { " E-2286G" , 12 },
7007+ { " E-2288G" , 16 },
7008+ { " E-2276M" , 12 },
7009+ { " E-2286M" , 16 },
7010+
7011+ // Xeon W
7012+ { " W-2102" , 4 },
7013+ { " W-2104" , 4 },
7014+ { " W-2123" , 8 },
7015+ { " W-2125" , 8 },
7016+ { " W-2133" , 12 },
7017+ { " W-2135" , 12 },
7018+ { " W-2140B" , 16 },
7019+ { " W-2145" , 16 },
7020+ { " W-2150B" , 20 },
7021+ { " W-2155" , 20 },
7022+ { " W-2170B" , 28 },
7023+ { " W-2175" , 28 },
7024+ { " W-2191B" , 36 },
7025+ { " W-2195" , 36 },
7026+ { " W-3175X" , 56 },
7027+ { " W-3223" , 16 },
7028+ { " W-3225" , 16 },
7029+ { " W-3235" , 24 },
7030+ { " W-3245" , 32 },
7031+ { " W-3245M" , 32 },
7032+ { " W-3265" , 48 },
7033+ { " W-3265M" , 48 },
7034+ { " W-3275" , 56 },
7035+ { " W-3275M" , 56 }
7036+ };
7037+
7038+ if (xeon_thread_database.count (model.string ) == 0 ) {
7039+ return false ;
7040+ }
7041+
7042+ const u8 threads = xeon_thread_database.at (model.string );
7043+
7044+ debug (" XEON_THREAD_MISMATCH: thread in database = " , static_cast <u32 >(threads));
7045+
7046+ return (std::thread::hardware_concurrency () != threads);
7047+ #endif
7048+ }
7049+ catch (...) {
7050+ debug (" INTEL_THREAD_MISMATCH: catched error, returned false" );
7051+ return false ;
7052+ }
7053+
68767054 struct core {
68777055 MSVC_DISABLE_WARNING (PADDING)
68787056 struct technique {
@@ -7462,7 +7640,8 @@ const std::map<VM::u8, VM::core::technique> VM::core::table = {
74627640 { VM::MUTEX, { 85 , VM::mutex }},
74637641 { VM::UPTIME, { 10 , VM::uptime }},
74647642 { VM::ODD_CPU_THREADS, { 80 , VM::odd_cpu_threads }},
7465- { VM::INTEL_THREAD_MISMATCH, { 70 , VM::intel_thread_mismatch }}
7643+ { VM::INTEL_THREAD_MISMATCH, { 85 , VM::intel_thread_mismatch }},
7644+ { VM::XEON_THREAD_MISMATCH, { 85 , VM::xeon_thread_mismatch }}
74667645
74677646 // __TABLE_LABEL, add your technique above
74687647 // { VM::FUNCTION, { POINTS, FUNCTION_POINTER }}
0 commit comments