Update ArmCPUDetect to fix potential crashes. Merge from Dolphin.

This commit is contained in:
Sacha 2014-06-08 05:09:46 +10:00
parent e69130b591
commit cb04c073b9
2 changed files with 66 additions and 94 deletions

View File

@ -29,155 +29,121 @@ const char procfile[] = "/proc/cpuinfo";
// https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-devices-system-cpu // https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-devices-system-cpu
const char syscpupresentfile[] = "/sys/devices/system/cpu/present"; const char syscpupresentfile[] = "/sys/devices/system/cpu/present";
char *GetCPUString() std::string GetCPUString()
{ {
const char marker[] = "Hardware\t: "; std::string line, marker = "Hardware\t: ";
char *cpu_string = 0; std::string cpu_string = "Unknown";
// Count the number of processor lines in /proc/cpuinfo std::fstream file;
char buf[1024]; if (!File::OpenCPPFile(file, procfile, std::ios::in))
FILE *fp; return cpu_string;
fp = fopen(procfile, "r");
if (!fp)
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; {
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
// INFO_LOG(BOOT, "CPU: %s", cpu_string); }
break;
} }
fclose(fp);
return cpu_string; return cpu_string;
} }
unsigned char GetCPUImplementer() unsigned char GetCPUImplementer()
{ {
const char marker[] = "CPU implementer\t: "; std::string line, marker = "CPU implementer\t: ";
char *implementer_string = 0;
unsigned char implementer = 0; unsigned char implementer = 0;
char buf[1024]; std::fstream file;
File::IOFile file(procfile, "r"); if (!File::OpenCPPFile(file, procfile, std::ios::in))
auto const fp = file.GetHandle();
if (!fp)
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: "; std::string line, marker = "CPU part\t: ";
char *part_string = 0;
unsigned short part = 0; unsigned short part = 0;
char buf[1024]; std::fstream file;
File::IOFile file(procfile, "r"); if (!File::OpenCPPFile(file, procfile, std::ios::in))
auto const fp = file.GetHandle();
if (!fp)
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%03gx", &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: "; std::string line, marker = "Features\t: ";
char buf[1024]; std::fstream file;
FILE *fp;
fp = fopen(procfile, "r"); if (!File::OpenCPPFile(file, procfile, std::ios::in))
if (!fp)
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 != NULL)
{ {
if (strstr(token, feature)) std::stringstream line_stream(line);
std::string token;
while (std::getline(line_stream, token, ' ')
{ {
fclose(fp); if (token == feature)
return true; return true;
} }
token = strtok(NULL, " ");
} }
} }
fclose(fp);
return false; return false;
} }
int GetCoreCount() int GetCoreCount()
{ {
const char marker[] = "processor\t: "; std::string line, marker = "processor\t: ";
int cores = 0; int cores = 1;
char buf[1024]; std::fstream file;
FILE *fp;
fp = fopen(syscpupresentfile, "r"); if (File::OpenCPPFile(file, syscpupresentfile, std::ios::in))
if (fp)
{ {
fgets(buf, sizeof(buf), fp); int low, high, found;
fclose(fp); std::getline(file, line);
found = sscanf(line, "%d-%d", &low, &high);
int low, high;
// Technically, this could be "1-2,4,8-23" but for ARM devices that seems unlikely.
int found = sscanf(buf, "%d-%d", &low, &high);
// Only a single number, so just one slot/core (actually threads.)
if (found == 1) if (found == 1)
return 1; return 1;
if (found == 2) if (found == 2)
return high - low + 1; return high - low + 1;
// Okay, let's fall back.
} }
fp = fopen(procfile, "r"); if (!File::OpenCPPFile(file, procfile, std::ios::in))
if (!fp) return 1;
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;
} }
fclose(fp);
return cores; return cores;
} }
#endif #endif
@ -192,11 +158,16 @@ CPUInfo::CPUInfo() {
void CPUInfo::Detect() void CPUInfo::Detect()
{ {
// Set some defaults here // Set some defaults here
// 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
@ -245,7 +216,7 @@ void CPUInfo::Detect()
bFP = false; bFP = false;
bASIMD = false; bASIMD = false;
#else // __linux__ #else // __linux__
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");
@ -291,6 +262,7 @@ std::string CPUInfo::Summarize()
if (bNEON) sum += ", NEON"; if (bNEON) sum += ", NEON";
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;
} }

2
native

@ -1 +1 @@
Subproject commit efd2cb0f618cc750842a9176487fee27599191cd Subproject commit 7ab6385a5e7a0fe18a59363739f1b10b13b6224a