|
|
@@ -448,6 +448,7 @@ public:
|
|
|
HP,
|
|
|
Hygon,
|
|
|
Zhaoxin,
|
|
|
+ Apple,
|
|
|
UnknownManufacturer
|
|
|
};
|
|
|
|
|
|
@@ -1752,6 +1753,8 @@ const char* SystemInformationImplementation::GetVendorID()
|
|
|
return "Chengdu Haiguang IC Design Co., Ltd.";
|
|
|
case Zhaoxin:
|
|
|
return "Shanghai Zhaoxin Semiconductor Co., Ltd.";
|
|
|
+ case Apple:
|
|
|
+ return "Apple";
|
|
|
case UnknownManufacturer:
|
|
|
default:
|
|
|
return "Unknown Manufacturer";
|
|
|
@@ -2135,6 +2138,8 @@ void SystemInformationImplementation::FindManufacturer(
|
|
|
this->ChipManufacturer = Motorola; // Motorola Microelectronics
|
|
|
else if (family.compare(0, 7, "PA-RISC") == 0)
|
|
|
this->ChipManufacturer = HP; // Hewlett-Packard
|
|
|
+ else if (this->ChipID.Vendor == "Apple")
|
|
|
+ this->ChipManufacturer = Apple; // Apple
|
|
|
else
|
|
|
this->ChipManufacturer = UnknownManufacturer; // Unknown manufacturer
|
|
|
}
|
|
|
@@ -4503,33 +4508,62 @@ unsigned int SystemInformationImplementation::GetNumberOfPhysicalCPU() const
|
|
|
return this->NumberOfPhysicalCPU;
|
|
|
}
|
|
|
|
|
|
-/** For Mac use sysctlbyname calls to find system info */
|
|
|
+#if defined(__APPLE__)
|
|
|
+static int kw_sysctlbyname_int32(const char* name, int32_t* value)
|
|
|
+{
|
|
|
+ size_t len = sizeof(int32_t);
|
|
|
+ int err = sysctlbyname(name, value, &len, nullptr, 0);
|
|
|
+ if (err == 0) {
|
|
|
+ assert(len == sizeof(int32_t));
|
|
|
+ }
|
|
|
+ return err;
|
|
|
+}
|
|
|
+
|
|
|
+static int kw_sysctlbyname_int64(const char* name, int64_t* value)
|
|
|
+{
|
|
|
+ size_t len = sizeof(int64_t);
|
|
|
+ int err = sysctlbyname(name, value, &len, nullptr, 0);
|
|
|
+ if (err == 0) {
|
|
|
+ assert(len == sizeof(int64_t));
|
|
|
+ }
|
|
|
+ return err;
|
|
|
+}
|
|
|
+#endif
|
|
|
+
|
|
|
+/** For Apple use sysctlbyname calls to find system info */
|
|
|
bool SystemInformationImplementation::ParseSysCtl()
|
|
|
{
|
|
|
#if defined(__APPLE__)
|
|
|
- char retBuf[128];
|
|
|
+ char tempBuff[128];
|
|
|
+ int32_t tempInt32 = 0;
|
|
|
+ int64_t tempInt64 = 0;
|
|
|
int err = 0;
|
|
|
- uint64_t value = 0;
|
|
|
- size_t len = sizeof(value);
|
|
|
- sysctlbyname("hw.memsize", &value, &len, nullptr, 0);
|
|
|
- this->TotalPhysicalMemory = static_cast<size_t>(value / 1048576);
|
|
|
+ size_t len;
|
|
|
+
|
|
|
+ this->TotalPhysicalMemory = 0;
|
|
|
+ err = kw_sysctlbyname_int64("hw.memsize", &tempInt64);
|
|
|
+ if (err == 0) {
|
|
|
+ this->TotalPhysicalMemory = static_cast<size_t>(tempInt64 / 1024 / 1024);
|
|
|
+ }
|
|
|
|
|
|
- // Parse values for Mac
|
|
|
this->AvailablePhysicalMemory = 0;
|
|
|
vm_statistics_data_t vmstat;
|
|
|
mach_msg_type_number_t count = HOST_VM_INFO_COUNT;
|
|
|
if (host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)&vmstat,
|
|
|
&count) == KERN_SUCCESS) {
|
|
|
- len = sizeof(value);
|
|
|
- err = sysctlbyname("hw.pagesize", &value, &len, nullptr, 0);
|
|
|
- int64_t available_memory =
|
|
|
- (vmstat.free_count + vmstat.inactive_count) * value;
|
|
|
- this->AvailablePhysicalMemory =
|
|
|
- static_cast<size_t>(available_memory / 1048576);
|
|
|
+ err = kw_sysctlbyname_int64("hw.pagesize", &tempInt64);
|
|
|
+ if (err == 0) {
|
|
|
+ int64_t available_memory =
|
|
|
+ (vmstat.free_count + vmstat.inactive_count) * tempInt64;
|
|
|
+ this->AvailablePhysicalMemory =
|
|
|
+ static_cast<size_t>(available_memory / 1024 / 1024);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
-# ifdef VM_SWAPUSAGE
|
|
|
// Virtual memory.
|
|
|
+ this->AvailableVirtualMemory = 0;
|
|
|
+ this->TotalVirtualMemory = 0;
|
|
|
+# ifdef VM_SWAPUSAGE
|
|
|
int mib[2] = { CTL_VM, VM_SWAPUSAGE };
|
|
|
unsigned int miblen =
|
|
|
static_cast<unsigned int>(sizeof(mib) / sizeof(mib[0]));
|
|
|
@@ -4538,78 +4572,98 @@ bool SystemInformationImplementation::ParseSysCtl()
|
|
|
err = sysctl(mib, miblen, &swap, &len, nullptr, 0);
|
|
|
if (err == 0) {
|
|
|
this->AvailableVirtualMemory =
|
|
|
- static_cast<size_t>(swap.xsu_avail / 1048576);
|
|
|
- this->TotalVirtualMemory = static_cast<size_t>(swap.xsu_total / 1048576);
|
|
|
+ static_cast<size_t>(swap.xsu_avail / 1024 / 1024);
|
|
|
+ this->TotalVirtualMemory =
|
|
|
+ static_cast<size_t>(swap.xsu_total / 1024 / 1024);
|
|
|
}
|
|
|
-# else
|
|
|
- this->AvailableVirtualMemory = 0;
|
|
|
- this->TotalVirtualMemory = 0;
|
|
|
# endif
|
|
|
|
|
|
// CPU Info
|
|
|
- len = sizeof(this->NumberOfPhysicalCPU);
|
|
|
- sysctlbyname("hw.physicalcpu", &this->NumberOfPhysicalCPU, &len, nullptr, 0);
|
|
|
- len = sizeof(this->NumberOfLogicalCPU);
|
|
|
- sysctlbyname("hw.logicalcpu", &this->NumberOfLogicalCPU, &len, nullptr, 0);
|
|
|
-
|
|
|
- int cores_per_package = 0;
|
|
|
- len = sizeof(cores_per_package);
|
|
|
- err = sysctlbyname("machdep.cpu.cores_per_package", &cores_per_package, &len,
|
|
|
- nullptr, 0);
|
|
|
- // That name was not found, default to 1
|
|
|
- this->Features.ExtendedFeatures.LogicalProcessorsPerPhysical =
|
|
|
- err != 0 ? 1 : static_cast<unsigned char>(cores_per_package);
|
|
|
+ this->NumberOfPhysicalCPU = 1;
|
|
|
+ err = kw_sysctlbyname_int32("hw.physicalcpu", &tempInt32);
|
|
|
+ if (err == 0) {
|
|
|
+ this->NumberOfPhysicalCPU = tempInt32;
|
|
|
+ }
|
|
|
|
|
|
- len = sizeof(value);
|
|
|
- sysctlbyname("hw.cpufrequency", &value, &len, nullptr, 0);
|
|
|
- this->CPUSpeedInMHz = static_cast<float>(value) / 1000000;
|
|
|
+ this->NumberOfLogicalCPU = 1;
|
|
|
+ err = kw_sysctlbyname_int32("hw.logicalcpu", &tempInt32);
|
|
|
+ if (err == 0) {
|
|
|
+ this->NumberOfLogicalCPU = tempInt32;
|
|
|
+ }
|
|
|
+
|
|
|
+ this->Features.ExtendedFeatures.LogicalProcessorsPerPhysical = 1;
|
|
|
+ err = kw_sysctlbyname_int32("machdep.cpu.cores_per_package", &tempInt32);
|
|
|
+ if (err == 0) {
|
|
|
+ this->Features.ExtendedFeatures.LogicalProcessorsPerPhysical = tempInt32;
|
|
|
+ }
|
|
|
+
|
|
|
+ this->CPUSpeedInMHz = 0;
|
|
|
+ err = kw_sysctlbyname_int64("hw.cpufrequency", &tempInt64);
|
|
|
+ if (err == 0) {
|
|
|
+ this->CPUSpeedInMHz = static_cast<float>(tempInt64) / 1000000.0f;
|
|
|
+ }
|
|
|
|
|
|
// Chip family
|
|
|
- len = sizeof(this->ChipID.Family);
|
|
|
- // Seems only the intel chips will have this name so if this fails it is
|
|
|
- // probably a PPC machine
|
|
|
- err =
|
|
|
- sysctlbyname("machdep.cpu.family", &this->ChipID.Family, &len, nullptr, 0);
|
|
|
+ // Seems only the Intel chips will have this name so if this fails it is
|
|
|
+ // a PowerPC or ARM, or something unknown
|
|
|
+ this->ChipID.Vendor = "";
|
|
|
+ this->ChipID.Family = 0;
|
|
|
+ this->ChipID.Model = 0;
|
|
|
+ this->ChipID.Revision = 0;
|
|
|
+ err = kw_sysctlbyname_int32("machdep.cpu.family", &tempInt32);
|
|
|
if (err != 0) // Go back to names we know but are less descriptive
|
|
|
{
|
|
|
- this->ChipID.Family = 0;
|
|
|
- ::memset(retBuf, 0, 128);
|
|
|
- len = 32;
|
|
|
- err = sysctlbyname("hw.machine", &retBuf, &len, nullptr, 0);
|
|
|
- std::string machineBuf(retBuf);
|
|
|
- if (machineBuf.find_first_of("Power") != std::string::npos) {
|
|
|
- this->ChipID.Vendor = "IBM";
|
|
|
- len = sizeof(this->ChipID.Family);
|
|
|
- err = sysctlbyname("hw.cputype", &this->ChipID.Family, &len, nullptr, 0);
|
|
|
- len = sizeof(this->ChipID.Model);
|
|
|
- err =
|
|
|
- sysctlbyname("hw.cpusubtype", &this->ChipID.Model, &len, nullptr, 0);
|
|
|
- this->FindManufacturer();
|
|
|
+ ::memset(tempBuff, 0, sizeof(tempBuff));
|
|
|
+ len = sizeof(tempBuff) - 1; // leave a byte for null termination
|
|
|
+ err = sysctlbyname("hw.machine", &tempBuff, &len, nullptr, 0);
|
|
|
+ if (err == 0) {
|
|
|
+ std::string machineBuf(tempBuff);
|
|
|
+ if (machineBuf.find_first_of("Power") != std::string::npos) {
|
|
|
+ this->ChipID.Vendor = "IBM";
|
|
|
+
|
|
|
+ err = kw_sysctlbyname_int32("hw.cputype", &tempInt32);
|
|
|
+ if (err == 0) {
|
|
|
+ this->ChipID.Family = tempInt32;
|
|
|
+ }
|
|
|
+
|
|
|
+ err = kw_sysctlbyname_int32("hw.cpusubtype", &tempInt32);
|
|
|
+ if (err == 0) {
|
|
|
+ this->ChipID.Model = tempInt32;
|
|
|
+ }
|
|
|
+
|
|
|
+ this->FindManufacturer();
|
|
|
+ } else if (machineBuf.find_first_of("arm64") != std::string::npos) {
|
|
|
+ this->ChipID.Vendor = "Apple";
|
|
|
+
|
|
|
+ this->FindManufacturer();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // Should be an Intel Chip.
|
|
|
+ err = kw_sysctlbyname_int32("machdep.cpu.family", &tempInt32);
|
|
|
+ if (err == 0) {
|
|
|
+ this->ChipID.Family = tempInt32;
|
|
|
}
|
|
|
- } else // Should be an Intel Chip.
|
|
|
- {
|
|
|
- len = sizeof(this->ChipID.Family);
|
|
|
- err = sysctlbyname("machdep.cpu.family", &this->ChipID.Family, &len,
|
|
|
- nullptr, 0);
|
|
|
|
|
|
- ::memset(retBuf, 0, 128);
|
|
|
- len = 128;
|
|
|
- err = sysctlbyname("machdep.cpu.vendor", retBuf, &len, nullptr, 0);
|
|
|
// Chip Vendor
|
|
|
- this->ChipID.Vendor = retBuf;
|
|
|
+ ::memset(tempBuff, 0, sizeof(tempBuff));
|
|
|
+ len = sizeof(tempBuff) - 1; // leave a byte for null termination
|
|
|
+ err = sysctlbyname("machdep.cpu.vendor", tempBuff, &len, nullptr, 0);
|
|
|
+ if (err == 0) {
|
|
|
+ this->ChipID.Vendor = tempBuff;
|
|
|
+ }
|
|
|
this->FindManufacturer();
|
|
|
|
|
|
// Chip Model
|
|
|
- len = sizeof(value);
|
|
|
- err = sysctlbyname("machdep.cpu.model", &value, &len, nullptr, 0);
|
|
|
- this->ChipID.Model = static_cast<int>(value);
|
|
|
+ err = kw_sysctlbyname_int32("machdep.cpu.model", &tempInt32);
|
|
|
+ if (err == 0) {
|
|
|
+ this->ChipID.Model = tempInt32;
|
|
|
+ }
|
|
|
|
|
|
// Chip Stepping
|
|
|
- len = sizeof(value);
|
|
|
- value = 0;
|
|
|
- err = sysctlbyname("machdep.cpu.stepping", &value, &len, nullptr, 0);
|
|
|
- if (!err) {
|
|
|
- this->ChipID.Revision = static_cast<int>(value);
|
|
|
+ err = kw_sysctlbyname_int32("machdep.cpu.stepping", &tempInt32);
|
|
|
+ if (err == 0) {
|
|
|
+ this->ChipID.Revision = tempInt32;
|
|
|
}
|
|
|
|
|
|
// feature string
|
|
|
@@ -4632,36 +4686,36 @@ bool SystemInformationImplementation::ParseSysCtl()
|
|
|
len = allocSize - 2; // keep space for leading and trailing space
|
|
|
err = sysctlbyname("machdep.cpu.features", buf + 1, &len, nullptr, 0);
|
|
|
}
|
|
|
- if (!err && buf && len) {
|
|
|
+ if (err == 0 && buf && len) {
|
|
|
// now we can match every flags as space + flag + space
|
|
|
buf[len + 1] = ' ';
|
|
|
std::string cpuflags(buf, len + 2);
|
|
|
|
|
|
- if ((cpuflags.find(" FPU ") != std::string::npos)) {
|
|
|
+ if (cpuflags.find(" FPU ") != std::string::npos) {
|
|
|
this->Features.HasFPU = true;
|
|
|
}
|
|
|
- if ((cpuflags.find(" TSC ") != std::string::npos)) {
|
|
|
+ if (cpuflags.find(" TSC ") != std::string::npos) {
|
|
|
this->Features.HasTSC = true;
|
|
|
}
|
|
|
- if ((cpuflags.find(" MMX ") != std::string::npos)) {
|
|
|
+ if (cpuflags.find(" MMX ") != std::string::npos) {
|
|
|
this->Features.HasMMX = true;
|
|
|
}
|
|
|
- if ((cpuflags.find(" SSE ") != std::string::npos)) {
|
|
|
+ if (cpuflags.find(" SSE ") != std::string::npos) {
|
|
|
this->Features.HasSSE = true;
|
|
|
}
|
|
|
- if ((cpuflags.find(" SSE2 ") != std::string::npos)) {
|
|
|
+ if (cpuflags.find(" SSE2 ") != std::string::npos) {
|
|
|
this->Features.HasSSE2 = true;
|
|
|
}
|
|
|
- if ((cpuflags.find(" APIC ") != std::string::npos)) {
|
|
|
+ if (cpuflags.find(" APIC ") != std::string::npos) {
|
|
|
this->Features.HasAPIC = true;
|
|
|
}
|
|
|
- if ((cpuflags.find(" CMOV ") != std::string::npos)) {
|
|
|
+ if (cpuflags.find(" CMOV ") != std::string::npos) {
|
|
|
this->Features.HasCMOV = true;
|
|
|
}
|
|
|
- if ((cpuflags.find(" MTRR ") != std::string::npos)) {
|
|
|
+ if (cpuflags.find(" MTRR ") != std::string::npos) {
|
|
|
this->Features.HasMTRR = true;
|
|
|
}
|
|
|
- if ((cpuflags.find(" ACPI ") != std::string::npos)) {
|
|
|
+ if (cpuflags.find(" ACPI ") != std::string::npos) {
|
|
|
this->Features.HasACPI = true;
|
|
|
}
|
|
|
}
|
|
|
@@ -4669,21 +4723,29 @@ bool SystemInformationImplementation::ParseSysCtl()
|
|
|
}
|
|
|
|
|
|
// brand string
|
|
|
- ::memset(retBuf, 0, sizeof(retBuf));
|
|
|
- len = sizeof(retBuf);
|
|
|
- err = sysctlbyname("machdep.cpu.brand_string", retBuf, &len, nullptr, 0);
|
|
|
- if (!err) {
|
|
|
- this->ChipID.ProcessorName = retBuf;
|
|
|
- this->ChipID.ModelName = retBuf;
|
|
|
+ this->ChipID.ProcessorName = "";
|
|
|
+ this->ChipID.ModelName = "";
|
|
|
+ ::memset(tempBuff, 0, sizeof(tempBuff));
|
|
|
+ len = sizeof(tempBuff) - 1; // leave a byte for null termination
|
|
|
+ err = sysctlbyname("machdep.cpu.brand_string", tempBuff, &len, nullptr, 0);
|
|
|
+ if (err == 0) {
|
|
|
+ this->ChipID.ProcessorName = tempBuff;
|
|
|
+ this->ChipID.ModelName = tempBuff;
|
|
|
}
|
|
|
|
|
|
- // Cache size
|
|
|
- len = sizeof(value);
|
|
|
- err = sysctlbyname("hw.l1icachesize", &value, &len, nullptr, 0);
|
|
|
- this->Features.L1CacheSize = static_cast<int>(value);
|
|
|
- len = sizeof(value);
|
|
|
- err = sysctlbyname("hw.l2cachesize", &value, &len, nullptr, 0);
|
|
|
- this->Features.L2CacheSize = static_cast<int>(value);
|
|
|
+ // L1 Cache size
|
|
|
+ this->Features.L1CacheSize = 0;
|
|
|
+ err = kw_sysctlbyname_int64("hw.l1icachesize", &tempInt64);
|
|
|
+ if (err == 0) {
|
|
|
+ this->Features.L1CacheSize = static_cast<int>(tempInt64);
|
|
|
+ }
|
|
|
+
|
|
|
+ // L2 Cache size
|
|
|
+ this->Features.L2CacheSize = 0;
|
|
|
+ err = kw_sysctlbyname_int64("hw.l2cachesize", &tempInt64);
|
|
|
+ if (err == 0) {
|
|
|
+ this->Features.L2CacheSize = static_cast<int>(tempInt64);
|
|
|
+ }
|
|
|
|
|
|
return true;
|
|
|
#else
|