________________________________________________________________________
Applicable Environment
________________________________________________________________________
- Topic: How to get current CPU usage (from code)
 
- SDP: 6.4.1
- Target: Any supported target
 
________________________________________________________________________
Recommendation________________________________________________________________________
 
The program below will print the current CPU usage for each CPU in the system.  It can be built as follows:
# qcc cpumon.c -o cpumon
It's output looks like:
# ./cpumon
System has: 1 CPUs
CPU #0: 100.000000
CPU #0: 3.084559
CPU #0: 2.492471
#include <atomic.h>
#include <libc.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/iofunc.h>
#include <sys/neutrino.h>
#include <sys/resmgr.h>
#include <sys/syspage.h>
#include <unistd.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/debug.h>
#include <sys/procfs.h>
#include <sys/syspage.h>
#include <sys/neutrino.h>
#include <sys/time.h>
#include <time.h>
#include <fcntl.h>
#include <devctl.h>
#include <errno.h>
#define MAX_CPUS 32
static float 	Loads[MAX_CPUS];
static _uint64	LastSutime[MAX_CPUS];
static _uint64  LastNsec[MAX_CPUS];
static int	ProcFd = -1;
static int 	NumCpus = 0;
 
int 
find_ncpus(void) {
	return NumCpus; 
}
int 
get_cpu(int cpu) {
	int ret;	
	ret = (int)Loads[ cpu % MAX_CPUS ];
	ret = max(0,ret);
	ret = min(100,ret);
	return( ret );
}
static 
_uint64 nanoseconds( void ) {
    _uint64 sec, usec;
    struct timeval tval;
    gettimeofday( &tval, NULL );
    sec = tval.tv_sec;
    usec = tval.tv_usec;
    return( ( ( sec * 1000000 ) + usec ) * 1000 );
}
int
sample_cpus( void ) {
    int i;
    debug_thread_t debug_data;
    _uint64 current_nsec, sutime_delta, time_delta;
    memset( &debug_data, 0, sizeof( debug_data ) );
    for( i=0; i<NumCpus; i++ ) {
        /* Get the sutime of the idle thread #i+1 */
        debug_data.tid = i + 1;
        devctl( ProcFd, DCMD_PROC_TIDSTATUS, 
                &debug_data, sizeof( debug_data ), NULL );
        /* Get the current time */
        current_nsec = nanoseconds(); 
        /* Get the deltas between now and the last samples */
        sutime_delta = debug_data.sutime - LastSutime[i];
        time_delta = current_nsec - LastNsec[i];
        
        /* Figure out the load */
        Loads[i] = 100.0 - ( (float)( sutime_delta * 100 ) / (float)time_delta );
        /* 
         * Flat out strange rounding issues.
         */
        if( Loads[i] < 0 ) {
            Loads[i] = 0;
        }
        /* Keep these for reference in the next cycle */
        LastNsec[i] = current_nsec;
        LastSutime[i] = debug_data.sutime;
    }
    return EOK;
}
int 
init_cpu( void ) {
    int i;
    debug_thread_t debug_data;
    memset( &debug_data, 0, sizeof( debug_data ) );
    /*
     * Open a connection to proc to talk over.
     */
    ProcFd = open( "/proc/1/as", O_RDONLY );
    if( ProcFd == -1 ) {
        fprintf( stderr, "pload: Unable to access procnto: %s\n", 
                 strerror( errno ) );
        fflush( stderr );
        return -1;
    }
	i = fcntl(ProcFd,F_GETFD);
        
	if(i != -1)
	{
		i |= FD_CLOEXEC;
		if(fcntl(ProcFd,F_SETFD,i) != -1)
		{
		    /* Grab this value */
		    NumCpus = _syspage_ptr->num_cpu;
		    /* Get a starting point for the comparisons */
		    for( i=0; i<NumCpus; i++ ) {
		        /* 
		         * the sutime of idle thread is how much 
		         * time that thread has been using, we can compare this
		         * against how much time has passed to get an idea of the
		         * load on the system.
		         */
		        debug_data.tid = i + 1;
		        devctl( ProcFd, DCMD_PROC_TIDSTATUS, &debug_data, sizeof( debug_data ), NULL );
		        LastSutime[i] = debug_data.sutime;
		        LastNsec[i] = nanoseconds();
		    }
		    
		    return(EOK);
	    }
	}
	
	close(ProcFd);
	return(-1);
}
void close_cpu(void)
{
	if(ProcFd != -1)
	{
		close(ProcFd);
		ProcFd = -1;
	}
}
int main(int argc, char* argv[])
{
   int i,j;
   init_cpu();
   printf("System has: %d CPUs\n", NumCpus);
   for(i=0; i<20; i++) {
     sample_cpus();
     for(j=0; j<NumCpus;j++) 
        printf("CPU #%d: %f\n", j, Loads[j]);
     sleep(1); 
   }
   close_cpu();
}
________________________________________________________________________
NOTE:
 This entry has been validated against the SDP version listed above. Use
 caution when considering this advice for any other SDP version. For 
supported releases, please reach out to QNX Technical Support if you have any questions/concerns. ________________________________________________________________________