| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258 | //-----------------------------------------------------------------------------// Copyright (c) 2012 GarageGames, LLC//// Permission is hereby granted, free of charge, to any person obtaining a copy// of this software and associated documentation files (the "Software"), to// deal in the Software without restriction, including without limitation the// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or// sell copies of the Software, and to permit persons to whom the Software is// furnished to do so, subject to the following conditions://// The above copyright notice and this permission notice shall be included in// all copies or substantial portions of the Software.//// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS// IN THE SOFTWARE.//-----------------------------------------------------------------------------#if !defined( __APPLE__ ) && !defined( __FreeBSD__ )#include <fstream>#include <iostream>#include <string>#include <sstream>#include <vector>#include "platform/platform.h"#include "platformPOSIX/platformPOSIX.h"#include "platform/platformCPUCount.h"#include "console/console.h"#include <unistd.h>Platform::SystemInfo_struct Platform::SystemInfo;// trim from start (in place)static inline void ltrim(std::string &s) {    s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](unsigned char ch) {        return !std::isspace(ch);    }));}// trim from end (in place)static inline void rtrim(std::string &s) {    s.erase(std::find_if(s.rbegin(), s.rend(), [](unsigned char ch) {        return !std::isspace(ch);    }).base(), s.end());}static void getCPUInformation(){    std::string vendorString;    std::string brandString;    std::ifstream cpuInfo("/proc/cpuinfo");    U32 logicalCoreCount = 0;    U32 physicalCoreCount = 1;    if (cpuInfo.is_open())    {        // Load every line of the CPU Info        std::string line;        while (std::getline(cpuInfo, line))        {            std::string fieldName = line.substr(0, line.find(":"));            rtrim(fieldName);            // Entries are newline separated            if (fieldName == "")            {                ++logicalCoreCount;                continue;            }            std::string fieldValue = line.substr(line.find(":") + 1, line.length());            ltrim(fieldValue);            rtrim(fieldValue);            // Load fields            if (fieldName == "vendor_id")            {                vendorString = fieldValue.c_str();            }            else if (fieldName == "model name")            {                brandString = fieldValue.c_str();            }            else if (fieldName == "cpu cores")            {                physicalCoreCount = dAtoui(fieldValue.c_str());            }            else if (fieldName == "flags")            {                std::vector<std::string> flags;                std::istringstream flagStream(fieldValue);                std::string currentFlag;                while (std::getline(flagStream, currentFlag, ' '))                {                    flags.push_back(currentFlag);                }                // Set CPU flags                if (std::find(flags.begin(), flags.end(), "fpu") != flags.end())                {                    Platform::SystemInfo.processor.properties |= CPU_PROP_FPU;                }                if (std::find(flags.begin(), flags.end(), "sse3") != flags.end())                {                    Platform::SystemInfo.processor.properties |= CPU_PROP_SSE3;                }                if (std::find(flags.begin(), flags.end(), "avx") != flags.end())                {                    Platform::SystemInfo.processor.properties |= CPU_PROP_AVX;                }                if (std::find(flags.begin(), flags.end(), "ssse3") != flags.end())                {                    Platform::SystemInfo.processor.properties |= CPU_PROP_SSE3ex;                }                if (std::find(flags.begin(), flags.end(), "sse") != flags.end())                {                    Platform::SystemInfo.processor.properties |= CPU_PROP_SSE;                }                if (std::find(flags.begin(), flags.end(), "sse2") != flags.end())                {                    Platform::SystemInfo.processor.properties |= CPU_PROP_SSE2;                }                if (std::find(flags.begin(), flags.end(), "sse4_1") != flags.end())                {                    Platform::SystemInfo.processor.properties |= CPU_PROP_SSE4_1;                }                if (std::find(flags.begin(), flags.end(), "sse4_2") != flags.end())                {                    Platform::SystemInfo.processor.properties |= CPU_PROP_SSE4_2;                }                if (std::find(flags.begin(), flags.end(), "mmx") != flags.end())                {                    Platform::SystemInfo.processor.properties |= CPU_PROP_MMX;                }            }        }        cpuInfo.close();    }    else    {        logicalCoreCount = 1;    }    Platform::SystemInfo.processor.numLogicalProcessors = logicalCoreCount;    Platform::SystemInfo.processor.numPhysicalProcessors = physicalCoreCount;    Platform::SystemInfo.processor.isHyperThreaded = logicalCoreCount != physicalCoreCount;    Platform::SystemInfo.processor.isMultiCore = physicalCoreCount != 1;    Platform::SystemInfo.processor.numLogicalProcessors = logicalCoreCount;    Platform::SystemInfo.processor.numPhysicalProcessors = physicalCoreCount;    if (Platform::SystemInfo.processor.isMultiCore)    {        Platform::SystemInfo.processor.properties |= CPU_PROP_MP;    }    // Load processor base frequency    std::ifstream baseFrequencyStream("/sys/devices/system/cpu/cpu0/cpufreq/base_frequency");    if (baseFrequencyStream.is_open())    {        U32 baseFrequencyKHz = 0;        baseFrequencyStream >> baseFrequencyKHz;        Platform::SystemInfo.processor.mhz = baseFrequencyKHz / 1000;        baseFrequencyStream.close();    }    SetProcessorInfo(Platform::SystemInfo.processor, vendorString.c_str(), brandString.c_str());}void Processor::init(){    getCPUInformation();#if defined(TORQUE_CPU_X64) || defined(TORQUE_CPU_X32)    // Set sane default information    Platform::SystemInfo.processor.properties |= CPU_PROP_C | CPU_PROP_FPU | CPU_PROP_LE ;#elif defined(TORQUE_CPU_ARM32) || defined(TORQUE_CPU_ARM64)    Platform::SystemInfo.processor.type = CPU_ArmCompatible;    Platform::SystemInfo.processor.name = StringTable->insert("Unknown ARM Processor");    Platform::SystemInfo.processor.properties = CPU_PROP_C;#else#warning Unsupported CPU#endif    // Set 64bit flag#if defined(TORQUE_CPU_X64) || defined(TORQUE_CPU_ARM64)    Platform::SystemInfo.processor.properties |= CPU_PROP_64bit;#endif    // Once CPU information is resolved, produce an output like Windows does    Con::printf("Processor Init:");    Con::printf("   Processor: %s", Platform::SystemInfo.processor.name);    if (Platform::SystemInfo.processor.properties & CPU_PROP_MMX)        Con::printf("      MMX detected" );    if (Platform::SystemInfo.processor.properties & CPU_PROP_SSE)        Con::printf("      SSE detected" );    if (Platform::SystemInfo.processor.properties & CPU_PROP_SSE2)        Con::printf("      SSE2 detected" );    if (Platform::SystemInfo.processor.properties & CPU_PROP_SSE3)        Con::printf("      SSE3 detected" );    if (Platform::SystemInfo.processor.properties & CPU_PROP_SSE4_1)        Con::printf("      SSE4.1 detected" );    if (Platform::SystemInfo.processor.properties & CPU_PROP_SSE4_2)        Con::printf("      SSE4.2 detected" );    if (Platform::SystemInfo.processor.properties & CPU_PROP_AVX)        Con::printf("      AVX detected" );    if (Platform::SystemInfo.processor.properties & CPU_PROP_SSE3ex)        Con::printf("      SSE3ex detected" );    if (Platform::SystemInfo.processor.properties & CPU_PROP_MP)        Con::printf("   MultiCore CPU detected [%i cores, %i logical]", Platform::SystemInfo.processor.numPhysicalProcessors, Platform::SystemInfo.processor.numLogicalProcessors);    Con::printf(" ");}namespace CPUInfo{    EConfig CPUCount(U32 &logical, U32 &physical)    {        // We don't set logical or physical here because it's already been determined by this point        if (Platform::SystemInfo.processor.isHyperThreaded && Platform::SystemInfo.processor.numPhysicalProcessors == 1)        {            return CONFIG_SingleCoreHTEnabled;        }        else if (!Platform::SystemInfo.processor.isHyperThreaded && Platform::SystemInfo.processor.numPhysicalProcessors > 1)        {            return CONFIG_MultiCoreAndHTNotCapable;        }        else if (!Platform::SystemInfo.processor.isHyperThreaded && Platform::SystemInfo.processor.numPhysicalProcessors == 1)        {            return CONFIG_SingleCoreAndHTNotCapable;        }        return CONFIG_MultiCoreAndHTEnabled;    }}; // namespace CPUInfo#endif
 |