perfstat_cpu interface

The perfstat_cpu interface returns a set of structures of type perfstat_cpu_t, which is defined in the libperfstat.h file.

Selected fields from the perfstat_cpu_t structure include:
Item Descriptor
name Logical processor name (cpu0, cpu1, ...)
user Number of clock ticks spent in user mode
sys Number of clock ticks spent in system (kernel) mode
idle Number of clock ticks spent idle with no I/O pending
wait Number of clock ticks spent idle with I/O pending
syscall Number of system call executed
Several other CPU-related metrics (such as number of forks, read, write, and execs) are also returned. For a complete list, see the perfstat_cpu_t section in the libperfstat.h header.
The following code shows an example of how the perfstat_cpu interface is used:
#include <stdio.h>
#include <stdlib.h>
#include <libperfstat.h>

int main(int argc, char *argv[]) {
   int i, retcode, cputotal;
   perfstat_id_t firstcpu;
   perfstat_cpu_t *statp;
   
   /* check how many perfstat_cpu_t structures are available */
   cputotal =  perfstat_cpu(NULL, NULL, sizeof(perfstat_cpu_t), 0);
   
      /* check for error */
   if (cputotal <= 0)
   {
        perror("perfstat_cpu");
        exit(-1); 
   }
  
   /* allocate enough memory for all the structures */
   statp = calloc(cputotal,sizeof(perfstat_cpu_t));
   if(statp==NULL){
	printf("No sufficient memory\n");
	exit(-1);
   }
   
   /* set name to first cpu */
   strcpy(firstcpu.name, FIRST_CPU);
   
   /* ask to get all the structures available in one call */
   retcode = perfstat_cpu(&firstcpu, statp, sizeof(perfstat_cpu_t), cputotal);
   
   /* check for error */
   if (retcode <= 0)
   {
        perror("perfstat_cpu");
        exit(-1); 
   }
   
   /* return code is number of structures returned */
   
   for (i = 0; i < retcode; i++) {
      printf("\nStatistics for CPU : %s\n", statp[i].name);
      printf("------------------\n");
      printf("CPU user time (raw ticks)  : %llu\n", statp[i].user);
      printf("CPU sys  time (raw ticks)  : %llu\n", statp[i].sys);
      printf("CPU idle time (raw ticks)  : %llu\n", statp[i].idle);
      printf("CPU wait time (raw ticks)  : %llu\n", statp[i].wait);
      printf("number of syscalls         : %llu\n", statp[i].syscall);
      printf("number of readings         : %llu\n", statp[i].sysread);
      printf("number of writings         : %llu\n", statp[i].syswrite);
      printf("number of forks            : %llu\n", statp[i].sysfork);
      printf("number of execs            : %llu\n", statp[i].sysexec);
      printf("number of char read        : %llu\n", statp[i].readch);
      printf("number of char written     : %llu\n", statp[i].writech);
      }
}
The program displays an output that is similar to the following example output:
Statistics for CPU : cpu0
------------------
CPU user time (raw ticks)  : 2585
CPU sys  time (raw ticks)  : 25994
CPU idle time (raw ticks)  : 7688458
CPU wait time (raw ticks)  : 3207
number of syscalls         : 6051122
number of readings         : 436595
number of writings         : 1284469
number of forks            : 4804
number of execs            : 5420
number of char read        : 1014077004
number of char written     : 56464273

Statistics for CPU : cpu1
------------------
CPU user time (raw ticks)  : 23
CPU sys  time (raw ticks)  : 794
CPU idle time (raw ticks)  : 7703901
CPU wait time (raw ticks)  : 42
number of syscalls         : 66064
number of readings         : 3432
number of writings         : 20620
number of forks            : 412
number of execs            : 51
number of char read        : 7068025
number of char written     : 217425

Statistics for CPU : cpu2
------------------
CPU user time (raw ticks)  : 0
CPU sys  time (raw ticks)  : 720
CPU idle time (raw ticks)  : 7704041
CPU wait time (raw ticks)  : 0
number of syscalls         : 0
number of readings         : 0
number of writings         : 0
number of forks            : 0
number of execs            : 0
number of char read        : 0
number of char written     : 0

Statistics for CPU : cpu3
------------------
CPU user time (raw ticks)  : 0
CPU sys  time (raw ticks)  : 810
CPU idle time (raw ticks)  : 7703950
CPU wait time (raw ticks)  : 0
number of syscalls         : 0
number of readings         : 0
number of writings         : 0
number of forks            : 0
number of execs            : 0
number of char read        : 0
number of char written     : 0

Statistics for CPU : cpu4
------------------
CPU user time (raw ticks)  : 243
CPU sys  time (raw ticks)  : 1799
CPU idle time (raw ticks)  : 7702802
CPU wait time (raw ticks)  : 62
number of syscalls         : 722482
number of readings         : 34416
number of writings         : 2994
number of forks            : 597
number of execs            : 453
number of char read        : 128511349
number of char written     : 2352602

Statistics for CPU : cpu5
------------------
CPU user time (raw ticks)  : 0
CPU sys  time (raw ticks)  : 209834
CPU idle time (raw ticks)  : 7676489
CPU wait time (raw ticks)  : 0
number of syscalls         : 729
number of readings         : 42
number of writings         : 0
number of forks            : 16
number of execs            : 1
number of char read        : 14607
number of char written     : 0

Statistics for CPU : cpu6
------------------
CPU user time (raw ticks)  : 0
CPU sys  time (raw ticks)  : 210391
CPU idle time (raw ticks)  : 7677505
CPU wait time (raw ticks)  : 0
number of syscalls         : 0
number of readings         : 0
number of writings         : 0
number of forks            : 0
number of execs            : 0
number of char read        : 0
number of char written     : 0

Statistics for CPU : cpu7
------------------
CPU user time (raw ticks)  : 0
CPU sys  time (raw ticks)  : 209884
CPU idle time (raw ticks)  : 7675736
CPU wait time (raw ticks)  : 0
number of syscalls         : 0
number of readings         : 0
number of writings         : 0
number of forks            : 0
number of execs            : 0
number of char read        : 0
number of char written     : 0

In an environment where dynamic logical partitioning is used, the number of perfstat_cpu_t structures available is equal to the ncpus_high field in the perfstat_cpu_total_t. This number represents the highest index of any active processor since the last reboot. Kernel data structures holding performance metrics for processors are not deallocated when processors are turned offline or moved to a different partition and it stops updating the information. The CPUs field of the perfstat_cpu_total_t structure represents the number of active processors, but the perfstat_cpu interface returns ncpus_high structures.

Applications can detect offline or moved processors by checking clock-tick increments. If the sum of the user, sys, idle, and wait fields is identical for a given processor between two perfstat_cpu calls, that processor has been offline for the complete interval. If the sum multiplied by 10 ms (the value of a clock tick) does not match the time interval, the processor has not been online for the complete interval.

The preceding program emulates mpstat behavior and also shows how perfstat_cpu is used.