Use systemcfg APIs for CPU detection on AIX
authorKevin Adler <kadler@us.ibm.com>
Fri, 31 Jul 2020 01:52:16 +0000 (20:52 -0500)
committerKevin Adler <kadler@us.ibm.com>
Fri, 31 Jul 2020 02:06:40 +0000 (21:06 -0500)
AIX libc already provides ready access to an integer that contains a bit
identifying the CPU it's running on, so there's no need to call a
program and grep its output. Additionally, prtconf is not available in
the PASE runtime, which provides an AIX emulation layer on the IBM i
operating system.

The AIX systemcfg.h also provides macro definitions like POWER_8,
POWER_9, etc for all the bits defining the CPUs as well as macros like
__power_8(), __power_9_andup() that return booleans, but I did not use
them. Since these macros depend on the level of the OS in which it is
built, they may not be defined and instead the associated hex literals
are used directly.

cpuid_power.c

index 8f578d6..df3dc86 100644 (file)
@@ -38,6 +38,7 @@
 
 #include  <sys/utsname.h>
 #ifdef _AIX
+#include <sys/systemcfg.h>
 #include <sys/vminfo.h>
 #endif
 #ifdef __APPLE__
@@ -137,35 +138,19 @@ int detect(void){
 #endif
 
 #ifdef _AIX
-  FILE *infile;
-  char buffer[512], *p;
-
-  p = (char *)NULL;
-  infile = popen("prtconf|grep 'Processor Type'", "r");
-  while (fgets(buffer, sizeof(buffer), infile)){
-    if (!strncmp("Pro", buffer, 3)){
-       p = strchr(buffer, ':') + 2;
-#if 0
-       fprintf(stderr, "%s\n", p);
-#endif
-       break;
-      }
-  }
-
-  pclose(infile);
+  // Cast from int to unsigned to ensure comparisons work for all bits in
+  // the bit mask, even the top bit
+  unsigned implementation = (unsigned) _system_configuration.implementation;
 
-  if (strstr(p, "POWER3")) return CPUTYPE_POWER3;
-  if (strstr(p, "POWER4")) return CPUTYPE_POWER4;
-  if (strstr(p, "PPC970")) return CPUTYPE_PPC970;
-  if (strstr(p, "POWER5")) return CPUTYPE_POWER5;
-  if (strstr(p, "POWER6")) return CPUTYPE_POWER6;
-  if (strstr(p, "POWER7")) return CPUTYPE_POWER6;
-  if (strstr(p, "POWER8")) return CPUTYPE_POWER8;
-  if (strstr(p, "POWER9")) return CPUTYPE_POWER9;
-  if (strstr(p, "POWER10")) return CPUTYPE_POWER10;
-  if (strstr(p, "Cell")) return CPUTYPE_CELL;
-  if (strstr(p, "7447")) return CPUTYPE_PPCG4;
-  return CPUTYPE_POWER5;
+  if (implementation >= 0x40000u) return CPUTYPE_POWER10;
+  else if (implementation & 0x20000) return CPUTYPE_POWER9;
+  else if (implementation & 0x10000) return CPUTYPE_POWER8;
+  else if (implementation & 0x08000) return CPUTYPE_POWER7; // POWER 7
+  else if (implementation & 0x04000) return CPUTYPE_POWER6;
+  else if (implementation & 0x02000) return CPUTYPE_POWER5;
+  else if (implementation & 0x01000) return CPUTYPE_POWER4; // MPC7450
+  else if (implementation & 0x00800) return CPUTYPE_POWER4;
+  else return CPUTYPE_POWER3;
 #endif
 
 #ifdef __APPLE__