Display the Number of CPUs

Article ID: 56818

How Many CPUs Are in Your System?

As we evolve our programming styles, it may someday become important to know the number of CPUs currently installed on your system. The PC/Intel worlds refers to this as "cores," but we tend to use the term processors.

I wanted to know the number of CPUs on my system because, well, I just wanted to know. So I found a way to do it. It does require some MI programming, but the amount of code is so little that it warrants an RPG Coder installment.

To get the number of CPUs in stored in the Machine Attributes Record, there is, as you might expect, a Materialize Machine Attributes API (technically, it's an MI instruction) that will return this information to your program in a data structure. That instruction is MATMATR and, specifically, a variant of it called MATMATR1. I'm using the built-in version, so there's an underscore prefix. Here's the prototype for this instruction:

     D matmatr         PR                  extProc('_MATMATR1')
     D  MMTR_T                      256A   options(*VARSIZE)
     D  nOption                       5I 0 Const

Note that this API has an all uppercase name. There doesn't seem to be too much consistency in the way upper/lower case is used in these API/MI instruction names, so make sure you're using the correct spelling and upper/lowercase combination when prototyping them.

The first parameter is a data structure that will receive the CPU count. This data structure is defined as follows:

     D CPU_Count       DS                  Inz Qualified
     D  nSize                        10I 0 inz(%Size(CPU_COUNT))
     D  nBytesRtn                    10I 0
     D  count                         5U 0

The official name for this data structure is something like Materialize Machine Attributes Template, but I thought CPU Count was a bit easier to remember.

The CPU_COUNT data structure is used as input and output by the API.

The first subfield of CPU_COUNT needs to be a four-byte integer or BIN(4) as API documentation shows it. In RPG IV terms, this means a 10i0 value. This subfield must contain the length of the CPU_COUNT data structure itself. This helps the API know how much information it can return. Why? Because the API can return a lot more than just the number of CPUs.

The second subfield of CPU_COUNT is the number of bytes the API populated in the data structure upon return. If all goes well (and it should), it will set this subfield to 10.

The third subfield of CPU_COUNT is the number of CPUs on your system. This is a "short" or Bin(2) value. In RPG IV terms, this means a 5u0 value; the "u" data type means unsigned.

The second parameter is an option or control code that informs MATMATR1 of the type of information we want. The value we need to use here is X'01DC'. Just to make things easier, I've created a named constant called processor_cnt that contains this hexadecimal value.

     D processor_cnt   C                   Const(X'01DC')

 

RPG TnT: 101 Dynamic Tips 'n Techniques with RPG IV by Bob Cozzi is available now.
The latest book from author Bob Cozzi is 300 pages, containing 101 example RPG IV Tips and Techniques for everyday programming tasks, from date calculations, to regular express searches, to using APIs. Cozzi wrote down every cool technique he's found over the years, updated them and consolidated them into this compact book that is a great desktop companion. And it includes full example source code. Order your copy today.

You could call MATMATR1 directly and then retrieve CPU_COUNT.COUNT into your program. Or you could write a simple wrapper subprocedure, named GETCPUCNT, that simply returns this value to its caller. I've created one below: 

  Source Member: QCPYSRC(CPUCOUNT) Type: RPGLE

      /IF NOT DEFINED(CPU_COUNT)
      /DEFINE CPU_COUNT
     D GetCPUCount     PR            10U 0 EXTPROC('GETCPUCOUNT')
      /ENDIF
  Source Member: QRPGLESRC(CPUCOUNT) Type: RPGLE

     H NOMAIN  OPTION(*SRCSTMT)

      /include RPGCODER/QCPYSRC,cpucount
      
     P GetCPUCount     B                   Export
     D GetCPUCount     PI            10U 0

     D matmatr         PR                  extProc('_MATMATR1')
     D  MMTR_T                      256A   options(*VARSIZE)
     D  nOption                       5I 0 Const

     D CPU_Count       DS                  Inz Qualified
     D  nSize                        10I 0 inz(%Size(CPU_COUNT))
     D  nBytesRtn                    10I 0
     D  count                         5U 0

     D processor_cnt   C                   Const(X'01DC')

      /free
           matmatr(cpu_count : processor_cnt);
           return cpu_count.count;
      /end-free
     P GetCPUCount     E 

DSPCPUCNT CL Command

To illustrate this capability, I wrote a simple CL command that displays the system's CPU count on Command Entry; actually it writes the CPU count to the job log as an informational message. The source for the Command Definition and CL follows:

  Source Member: QCMDSRC(DSPCPUCNT) Type: CMD

 DSPCPUCNT:  CMD        PROMPT('Display System CPU Count')
             /*  Command processing program is: DSPCPUCNT  */ 
  Source Member: QCLSRC(DSPCPUCNT) Type: CLLE

 DSPCPUCNT:  PGM        /* CPP for the DSPCPUCNT CL Command */
             DCL        VAR(&COUNT) TYPE(*INT) LEN(4)
             DCL        VAR(&ACOUNT) TYPE(*CHAR) LEN(4)
             CALLPRC    PRC(GETCPUCOUNT) RTNVAL(&COUNT)
             CHGVAR     VAR(&ACOUNT) VALUE(&COUNT)
             SNDPGMMSG  MSGID(CPF9897) MSGF(QCPFMSG) +
                           MSGDTA(&ACOUNT *BCAT 'CPUs detected.') +
                           MSGTYPE(*INFO)
 ENDPGM:     ENDPGM 

To compile the source members, use PDM Option 15 for the CLLE and RPG IV source members, and use PDM Option 14 for the CMD source member. Then issue the following CRTPGM command:

   CRTPGM PGM(DSPCPUCNT) MODULE(DSPCPUCNT CPUCOUNT)

Then run the command to have the number of CPUs displayed in your job log or on Command Entry, as follows:

DSPCPUCNT

On my system, the following message was generated on Command Entry:

  > dspcpucnt          
    0004 CPUs detected.

Remember, all the source code featured in RPG Coder and our Tuesday Tips publications is available online. Visit RPGWorld.com and click the "Tuesday Tips Downloads" button to see what's available in the downloads section.

Bob Cozzi produces RPG World, his annual conference for RPG IV developers. Bob is currently on tour, speaking about RPG IV at RPG World Academy, a series of one-day seminars for RPG IV programmers being held throughout the United States. Sign up today to hear Bob in person. Visit www.RPGWorld.com and click on the Academy link for more details, dates, and locations.

Interesting program. I ran this on an LPAR with 4 CPU allocated and it reported 32 CPUs, which is correct for the hardware but not for the LPAR.
Hi Bob.
So you "found a way to do it." I found a forum entry almost 3 years old:

http://forums.systeminetwork.com/isnetforums/showthread.php?t=41943

But the author's name is Bruce, not Bob.

Regards, René.

ProVIP Sponsors

ProVIP Sponsors