Explorar o código

KWSys 2021-02-10 (dda7a943)

Code extracted from:

    https://gitlab.kitware.com/utils/kwsys.git

at commit dda7a943856ad22e374a9b0434727285461770a6 (master).

Upstream Shortlog
-----------------

Sean McBride (1):
      45e42f63 SystemInformation: Improve ParseSysCtl error checking
KWSys Upstream %!s(int64=4) %!d(string=hai) anos
pai
achega
0c57a39c41
Modificáronse 1 ficheiros con 154 adicións e 92 borrados
  1. 154 92
      SystemInformation.cxx

+ 154 - 92
SystemInformation.cxx

@@ -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