Merge pull request #455 from lioncash/arm-cpudetect-fix

Stringify ArmCPUDetect.cpp.
This commit is contained in:
Ryan Houdek 2014-06-02 20:10:39 -05:00
commit 3a06907653
1 changed files with 104 additions and 90 deletions

View File

@ -2,34 +2,37 @@
// Licensed under GPLv2 // Licensed under GPLv2
// Refer to the license.txt file included. // Refer to the license.txt file included.
#include <fstream>
#include <sstream>
#include <string>
#include "Common/Common.h" #include "Common/Common.h"
#include "Common/CPUDetect.h" #include "Common/CPUDetect.h"
#include "Common/FileUtil.h"
#include "Common/StringUtil.h" #include "Common/StringUtil.h"
// Only Linux platforms have /proc/cpuinfo // Only Linux platforms have /proc/cpuinfo
#if !defined(BLACKBERRY) && !defined(IOS) && !defined(__SYMBIAN32__) #if !defined(BLACKBERRY) && !defined(IOS) && !defined(__SYMBIAN32__)
const char procfile[] = "/proc/cpuinfo"; const char procfile[] = "/proc/cpuinfo";
char *GetCPUString() std::string GetCPUString()
{ {
const char marker[] = "Hardware\t: "; const std::string marker = "Hardware\t: ";
char *cpu_string = nullptr; std::string cpu_string = "Unknown";
// Count the number of processor lines in /proc/cpuinfo
char buf[1024];
File::IOFile file(procfile, "r"); std::string line;
auto const fp = file.GetHandle(); std::ifstream file(procfile);
if (!fp)
return 0;
while (fgets(buf, sizeof(buf), fp)) if (!file)
return cpu_string;
while (std::getline(file, line))
{ {
if (strncmp(buf, marker, sizeof(marker) - 1)) if (line.find(marker) != std::string::npos)
continue; {
cpu_string = buf + sizeof(marker) - 1; cpu_string = line.substr(marker.length());
cpu_string = strndup(cpu_string, strlen(cpu_string) - 1); // Strip the newline cpu_string.pop_back(); // Drop the new-line character
break; break;
}
} }
return cpu_string; return cpu_string;
@ -37,79 +40,74 @@ char *GetCPUString()
unsigned char GetCPUImplementer() unsigned char GetCPUImplementer()
{ {
const char marker[] = "CPU implementer\t: "; const std::string marker = "CPU implementer\t: ";
char *implementer_string = nullptr;
unsigned char implementer = 0; unsigned char implementer = 0;
char buf[1024];
File::IOFile file(procfile, "r"); std::string line;
auto const fp = file.GetHandle(); std::ifstream file(procfile);
if (!fp)
if (!file)
return 0; return 0;
while (fgets(buf, sizeof(buf), fp)) while (std::getline(file, line))
{ {
if (strncmp(buf, marker, sizeof(marker) - 1)) if (line.find(marker) != std::string::npos)
continue; {
implementer_string = buf + sizeof(marker) - 1; line = line.substr(marker.length());
implementer_string = strndup(implementer_string, strlen(implementer_string) - 1); // Strip the newline sscanf(line.c_str(), "0x%02hhx", &implementer);
sscanf(implementer_string, "0x%02hhx", &implementer); break;
break; }
} }
free(implementer_string);
return implementer; return implementer;
} }
unsigned short GetCPUPart() unsigned short GetCPUPart()
{ {
const char marker[] = "CPU part\t: "; const std::string marker = "CPU part\t: ";
char *part_string = nullptr;
unsigned short part = 0; unsigned short part = 0;
char buf[1024];
File::IOFile file(procfile, "r"); std::string line;
auto const fp = file.GetHandle(); std::ifstream file(procfile);
if (!fp)
if (!file)
return 0; return 0;
while (fgets(buf, sizeof(buf), fp)) while (std::getline(file, line))
{ {
if (strncmp(buf, marker, sizeof(marker) - 1)) if (line.find(marker) != std::string::npos)
continue; {
part_string = buf + sizeof(marker) - 1; line = line.substr(marker.length());
part_string = strndup(part_string, strlen(part_string) - 1); // Strip the newline sscanf(line.c_str(), "0x%03hx", &part);
sscanf(part_string, "0x%03hx", &part); break;
break; }
} }
free(part_string);
return part; return part;
} }
bool CheckCPUFeature(const char *feature) bool CheckCPUFeature(const std::string& feature)
{ {
const char marker[] = "Features\t: "; const std::string marker = "Features\t: ";
char buf[1024];
File::IOFile file(procfile, "r"); std::string line;
auto const fp = file.GetHandle(); std::ifstream file(procfile);
if (!fp)
if (!file)
return 0; return 0;
while (fgets(buf, sizeof(buf), fp)) while (std::getline(file, line))
{ {
if (strncmp(buf, marker, sizeof(marker) - 1)) if (line.find(marker) != std::string::npos)
continue;
char *featurestring = buf + sizeof(marker) - 1;
char *token = strtok(featurestring, " ");
while (token != nullptr)
{ {
if (strstr(token, feature)) std::stringstream line_stream(line);
return true; std::string token;
token = strtok(nullptr, " ");
while (std::getline(line_stream, token, ' '))
{
if (token == feature)
return true;
}
} }
} }
@ -124,20 +122,21 @@ int GetCoreCount()
#elif defined(BLACKBERRY) || defined(IOS) #elif defined(BLACKBERRY) || defined(IOS)
return 2; return 2;
#else #else
const char marker[] = "processor\t: "; const std::string marker = "processor\t: ";
int cores = 0; int cores = 0;
char buf[1024];
File::IOFile file(procfile, "r"); std::string line;
auto const fp = file.GetHandle(); std::ifstream file(procfile);
if (!fp)
if (!file)
return 0; return 0;
while (fgets(buf, sizeof(buf), fp)) while (std::getline(file, line))
{ {
if (strncmp(buf, marker, sizeof(marker) - 1)) if (line.find(marker) != std::string::npos)
continue; {
++cores; ++cores;
}
} }
return cores; return cores;
@ -146,7 +145,8 @@ int GetCoreCount()
CPUInfo cpu_info; CPUInfo cpu_info;
CPUInfo::CPUInfo() { CPUInfo::CPUInfo()
{
Detect(); Detect();
} }
@ -156,9 +156,15 @@ void CPUInfo::Detect()
// Set some defaults here // Set some defaults here
// When ARMv8 cpus come out, these need to be updated. // When ARMv8 cpus come out, these need to be updated.
HTT = false; HTT = false;
#ifdef _M_ARM_64
OS64bit = true;
CPU64bit = true;
Mode64bit = true;
#else
OS64bit = false; OS64bit = false;
CPU64bit = false; CPU64bit = false;
Mode64bit = false; Mode64bit = false;
#endif
vendor = VENDOR_ARM; vendor = VENDOR_ARM;
// Get the information about the CPU // Get the information about the CPU
@ -168,28 +174,35 @@ void CPUInfo::Detect()
bool isVFP4 = false; bool isVFP4 = false;
#ifdef IOS #ifdef IOS
isVFP3 = true; isVFP3 = true;
// Check for swift arch (VFP4`) // Check for swift arch (VFP4`)
#ifdef __ARM_ARCH_7S__ #ifdef __ARM_ARCH_7S__
isVFP4 = true; isVFP4 = true;
#endif // #ifdef __ARM_ARCH_7S__ #endif // #ifdef __ARM_ARCH_7S__
#elif defined(BLACKBERRY) #elif defined(BLACKBERRY)
isVFP3 = true; isVFP3 = true;
const char cpuInfoPath[] = "/pps/services/hw_info/inventory"; const char cpuInfoPath[] = "/pps/services/hw_info/inventory";
const char marker[] = "Processor_Name::"; const std::string marker = "Processor_Name::";
const char qcCPU[] = "MSM"; const std::string qcCPU = "MSM";
char buf[1024];
FILE* fp; std::string line;
if (fp = fopen(cpuInfoPath, "r")) std::ifstream file(cpuInfoPath);
if (file)
{ {
while (fgets(buf, sizeof(buf), fp)) while (std::getline(file, line))
{ {
if (strncmp(buf, marker, sizeof(marker) - 1)) if (line.find(marker) != std::string::npos)
continue; {
if (strncmp(buf + sizeof(marker) - 1, qcCPU, sizeof(qcCPU) - 1) == 0) std::string first_three_chars = line.substr(marker.length(), qcCPU.length());
isVFP4 = true;
break; if (first_three_chars == qcCPU)
{
isVFP4 = true;
}
break;
}
} }
fclose(fp);
} }
#endif #endif
// Hardcode this for now // Hardcode this for now
@ -209,7 +222,7 @@ void CPUInfo::Detect()
bFP = false; bFP = false;
bASIMD = false; bASIMD = false;
#else #else
strncpy(cpu_string, GetCPUString(), sizeof(cpu_string)); strncpy(cpu_string, GetCPUString().c_str(), sizeof(cpu_string));
bSwp = CheckCPUFeature("swp"); bSwp = CheckCPUFeature("swp");
bHalf = CheckCPUFeature("half"); bHalf = CheckCPUFeature("half");
bThumb = CheckCPUFeature("thumb"); bThumb = CheckCPUFeature("thumb");
@ -230,8 +243,8 @@ void CPUInfo::Detect()
bFP = CheckCPUFeature("fp"); bFP = CheckCPUFeature("fp");
bASIMD = CheckCPUFeature("asimd"); bASIMD = CheckCPUFeature("asimd");
#endif #endif
// On android, we build a separate library for ARMv7 so this is fine. // On android, we build a separate library for ARMv7 so this is fine.
// TODO: Check for ARMv7 on other platforms. // TODO: Check for ARMv7 on other platforms.
#if defined(__ARM_ARCH_7A__) #if defined(__ARM_ARCH_7A__)
bArmV7 = true; bArmV7 = true;
#else #else
@ -264,6 +277,7 @@ std::string CPUInfo::Summarize()
if (bVFPv4) sum += ", VFPv4"; if (bVFPv4) sum += ", VFPv4";
if (bIDIVa) sum += ", IDIVa"; if (bIDIVa) sum += ", IDIVa";
if (bIDIVt) sum += ", IDIVt"; if (bIDIVt) sum += ", IDIVt";
if (CPU64bit) sum += ", 64-bit";
return sum; return sum;
} }