#pragma region CPL License /* Nuclex Native Framework Copyright (C) 2002-2023 Nuclex Development Labs This library is free software; you can redistribute it and/or modify it under the terms of the IBM Common Public License as published by the IBM Corporation; either version 1.0 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the IBM Common Public License for more details. You should have received a copy of the IBM Common Public License along with this library */ #pragma endregion // CPL License #ifndef NUCLEX_PLATFORM_HARDWARE_WINDOWSBASICCPUINFOREADER_H #define NUCLEX_PLATFORM_HARDWARE_WINDOWSBASICCPUINFOREADER_H #include "Nuclex/Platform/Config.h" #if defined(NUCLEX_PLATFORM_WINDOWS) #include // for std::string #include // for std::size_t #include // for std::shared_ptr #include // for std::vector #include "../Platform/WindowsSysInfoApi.h" // for WindowsSysInfoApi, WindowsApi namespace Nuclex { namespace Platform { namespace Tasks { // ------------------------------------------------------------------------------------------- // class CancellationWatcher; // ------------------------------------------------------------------------------------------- // }}} // namespace Nuclex::Platform::Tasks namespace Nuclex { namespace Platform { namespace Hardware { // ------------------------------------------------------------------------------------------- // /// Queries physical and logical CPUs using the clasic Windows API class WindowsBasicCpuInfoReader { #pragma region struct ProcessorInfo /// Captures a summary of informations about one processor /// /// A processor is the term used in WBEM/WMI and the Windows API to refer to /// one hardware-integrated code execution unit, i.e. one CPU core without /// HyperThreading or one HyperThread in a CPU with HyperThreading. /// public: struct ProcessorInfo { /// Initializes a new processor info structure public: ProcessorInfo() : PhysicalCpuIndex(0), CoreIndex(0) {} // other members can start out with undefined values /// Index of the physical CPU the processor belongs to /// /// This is 1-based. If any entries have CPU index 0, it means Window did report /// only the processors as sharing a core, but not which physical CPU they belong to. /// public: std::size_t PhysicalCpuIndex; /// Index of a core this processor shares with other processors /// /// This is 1-based. If any entries have core index 0, it means Windows did report /// only the processors on a physical CPU, but not which core they are on. /// public: std::size_t CoreIndex; /// Name of the CPU this processor is a part of public: std::string Name; /// Default clock frequency the processor runs at public: double FrequencyInMhz; /// Value provided by the Windows 7 API to identify Eco cores public: std::uint8_t Efficiency; }; #pragma endregion // struct ProcessorInfo /// Initializes the collected informations in the CPU info reader public: WindowsBasicCpuInfoReader(); /// Frees all data stored in the CPU info reader public: ~WindowsBasicCpuInfoReader() = default; /// Fetches the informations using API methods introduced by Windows XP /// /// This is the only method that works reliably on 32-bit Windows systems. /// public: void FetchViaWindowsXpApi(); /// Fetches the informations using API methods introduced by Windows 7 /// /// On 64-bit Windows systems with more than 32 cores, this method will return garbage /// because Microsoft messed up when designing the extended API (see the Remarks section /// of on MSDN). /// public: void FetchViaWindowsSevenApi(); /// /// Ingests a logical processor information record generated by Windows' /// method /// /// Logical processor information to ingest private: void ingestLogicalProcessor( const ::SYSTEM_LOGICAL_PROCESSOR_INFORMATION &logicalProcessor ); /// /// Ingests a logical processor information record generated by Windows' /// method /// /// Logical processor information to ingest private: void ingestLogicalProcessor( const ::SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX &logicalProcessor ); /// Whether there are any cores using Hyper-Threading in the system public: bool UsesHyperThreading; /// True if an efficiency value other than zero was seen public: bool NonZeroEfficiencySpotted; /// Lowest efficiency value seen on any processor public: std::uint8_t LowestEfficiencySeen; /// Highest efficiency value seen on any processor public: std::uint8_t HighestEfficiencySeen; /// Number of physical CPUs reported public: std::size_t PhysicalCpuCount; /// Number of cores (shared by processors) present in the system public: std::size_t CoreCount; /// Number of threads (over all processors) the system runs simultaneously public: std::size_t ThreadCount; /// Processors reported by the Windows API /// /// Processors are split into groups (there could be one group per physical package /// or one group per 64 cores since that's the limit of bits the mask can store), /// all properties in the ProcessorInfo group are indices within its group. /// public: std::vector> GroupsOfProcessors; }; // ------------------------------------------------------------------------------------------- // }}} // namespace Nuclex::Platform::Hardware #endif // defined(NUCLEX_PLATFORM_WINDOWS) #endif // NUCLEX_PLATFORM_HARDWARE_WINDOWSBASICCPUINFOREADER_H