/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* bos720 src/bos/usr/ccs/lib/libperfstat/perfsample.c 1.1                */
/*                                                                        */
/* Licensed Materials - Property of IBM                                   */
/*                                                                        */
/* Restricted Materials of IBM                                            */
/*                                                                        */
/* COPYRIGHT International Business Machines Corp. 2000                   */
/* All Rights Reserved                                                    */
/*                                                                        */
/* US Government Users Restricted Rights - Use, duplication or            */
/* disclosure restricted by GSA ADP Schedule Contract with IBM Corp.      */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
/* Sample program illustrating the use of the libperfstat */

/* you can compile it using the command: *
 * cc -lperfstat sample.c                */

#include <libperfstat.h>
#include <stdio.h>
#include <stdlib.h>

static void __wait_for_return_key_to_proceed()
{
	printf("\tPress return key to proceed...\n");
	getchar();
}

int main(){
	int i, number_of_cpus, number_of_netinterfaces, return_code;
	perfstat_id_t name;
	perfstat_netinterface_t * perfstat_netinterface_buffer;
	perfstat_netinterface_t * netinterface_structure_pointer;
	perfstat_disk_total_t perfstat_disk_total_buffer;
	perfstat_cpu_t * perfstat_cpu_buffer;
	perfstat_cpu_t * cpu_structure_pointer;

	/* We Want to get statistics related to the  *
	 * individual network interfaces.            */
	
	/* We can notice that we could also get global network interface *
	 * information using the perfstat_netinterface_total function.   */
	
	/* We will get the individual info following the algorithm *
	 * described below                                         *
	 * - First : get the number of network interfaces          *
	 * - Second: allocate memory to the result buffer          *
	 * - Third : Fill this statistics buffer                   */
	
	/* First: get the number of network interfaces */
	number_of_netinterfaces = perfstat_netinterface(NULL,
	               NULL, sizeof(perfstat_netinterface_t), 0);
	if (number_of_netinterfaces == -1)
	{
		/* An error occured */
		perror("Error, could not get the number of network interfaces");
		__wait_for_return_key_to_proceed();
	}
	else
	{
		/* We can therefore allocate enough memory for the buffer */
		perfstat_netinterface_buffer = (perfstat_netinterface_t *)
		  malloc(number_of_netinterfaces * sizeof(perfstat_netinterface_t));
		
		if (perfstat_netinterface_buffer == NULL){
			/* oups, not enough memory available */
			fprintf(stderr,
			  "Error, could not allocate memory for %d perfstat_netinterface_t structures\n",
			  number_of_netinterfaces);
			__wait_for_return_key_to_proceed();
		}
		else
		{			
			/* In order to get all of the network interfaces statistics,       *
			 * we will first ask for the network interface which name is "",   *
			 * that can be considered as as an alias for the name of the first *
			 * network interface.                                              */
			strcpy(name.name, "");
			
			/* We can now fill the buffer */
			return_code = perfstat_netinterface(&name, perfstat_netinterface_buffer,
			                           sizeof(perfstat_netinterface_t), number_of_netinterfaces);
			if (return_code == -1)
			{
				/* An error occured */
				perror("Error, could not get the individual net interface statisctics");
				__wait_for_return_key_to_proceed();
			}
			else
			{
				/* Ok, we could get the statistics, we can now print it. */
				for(i = 0, netinterface_structure_pointer = perfstat_netinterface_buffer;
				    i < return_code;
				    i++, netinterface_structure_pointer++)
				{
					printf(">-- Statistics regarding the network interface : %s\n", netinterface_structure_pointer->name);
					printf("> Description of the network interface         : %s\n", netinterface_structure_pointer->description);
					printf("> Type the interface                           : %d\n", netinterface_structure_pointer->type);
					printf("> Network frame size                           : %llu\n", netinterface_structure_pointer->mtu);
					printf("> Packets received on interface                : %llu\n", netinterface_structure_pointer->ipackets);
					printf("> Input bytes on interface                     : %llu\n", netinterface_structure_pointer->ierrors);
					printf("> Input errors on interface                    : %llu\n", netinterface_structure_pointer->ibytes);
					printf("> Packets sent on interface                    : %llu\n", netinterface_structure_pointer->opackets);
					printf("> Output bytes on interface                    : %llu\n", netinterface_structure_pointer->obytes);
					printf("> Output errors on interface                   : %llu\n", netinterface_structure_pointer->oerrors);
					printf("> Collisions on csma interface                 : %llu\n", netinterface_structure_pointer->collisions);
					__wait_for_return_key_to_proceed();
				}
			}
		}
	}
	
	
	/* We now want to get statistics related to disks.    *
	 * Although we can have individual statistics for the *
	 *  disks, we will only get global ones               */
	 
	return_code = perfstat_disk_total(NULL, &perfstat_disk_total_buffer,
			                           sizeof(perfstat_disk_total_t), 1);
	if (return_code == -1)
	{
		/* An error occured */
		perror("Error, could not get the global disks statisctics");
		__wait_for_return_key_to_proceed();
	}
	else
	{
		/* Ok, we could get the statistics, we can now print it. */
		printf("> Number of disks                    : %d\n",perfstat_disk_total_buffer.number);
		printf("> Sum of the size of the disks       : %llu MB\n",perfstat_disk_total_buffer.size);
		printf("> Sum of the free space of the disks : %llu MB\n",perfstat_disk_total_buffer.free);
		printf("> Average xfer rate capability       : %llu kbytes/sec\n",perfstat_disk_total_buffer.xrate);
		printf("> Total transfers to/from disks      : %llu\n",perfstat_disk_total_buffer.xfers);
		printf("> Blocks written to all disks        : %llu\n",perfstat_disk_total_buffer.wblks);
		printf("> Blocks read from all disks         : %llu\n",perfstat_disk_total_buffer.rblks);
		printf("> Amount of time disks are active    : %llu\n",perfstat_disk_total_buffer.time);
		__wait_for_return_key_to_proceed();
	}
	
	
	
	/* We will now illustrate the use of a fixed size buffer.     *
	 * In order to get all of the statistics related to the CPUs, *
	 *  we will call perfstat_cpu several times.                  *
	 * Each call will retrieve a part of the data thanks to the   *
	 *  buffer.                                                   */

	/* Yet, one should know that in terms of performance, using this *
	 * method to get the statistics won't be as efficient as calling *
	 * perfstat_cpu once.                                            */
	 
	/* We must deal with the first element (we can call it "") */
	strcpy(name.name, "");
	perfstat_cpu_buffer = (perfstat_cpu_t *)malloc(5*sizeof(perfstat_cpu_t));
	if (perfstat_cpu_buffer == NULL){
		/* oups, not enough memory available */
		fprintf(stderr,
		  "Error, could not allocate memory for %d perfstat_cpu_t structures\n",
		  number_of_cpus);
		__wait_for_return_key_to_proceed();
	}
	else
	{
		/* ok, the malloc succeded */
		do
		{
			return_code = perfstat_cpu(&name, perfstat_cpu_buffer,
		                           	sizeof(perfstat_cpu_t), 5);
			if (return_code == -1)
			{
				/* An error occured */
				perror("Error, could not get the individual CPUs statisctics");
				__wait_for_return_key_to_proceed();
			}
			else
			{
				/* Now we can display the available results. The number of  *
				 * results retrieved is stored in the return_code.          */
				 
				for (i = 0, cpu_structure_pointer = perfstat_cpu_buffer;
				     i < return_code;
					  i++, cpu_structure_pointer++)
				{
					printf(">-- Statistics regarding the CPU : %s\n", cpu_structure_pointer->name);
					printf("> User time used                 : %llu ticks\n", cpu_structure_pointer->user);
					printf("> System time used               : %llu ticks\n", cpu_structure_pointer->sys);
					printf("> Idle time used                 : %llu ticks\n", cpu_structure_pointer->idle);
					printf("> Wait time used                 : %llu ticks\n", cpu_structure_pointer->wait);
					printf("> Number of process switch       : %llu\n", cpu_structure_pointer->pswitch);
					printf("> Number of syscalls             : %llu\n", cpu_structure_pointer->syscall);
					printf("> Number of system read          : %llu\n", cpu_structure_pointer->sysread);
					printf("> Number of system write         : %llu\n", cpu_structure_pointer->syswrite);
					printf("> Number of forks                : %llu\n", cpu_structure_pointer->sysfork);
					printf("> Number of execs                : %llu\n", cpu_structure_pointer->sysexec);
					printf("> Number of read characters      : %llu\n", cpu_structure_pointer->readch);
					printf("> Number of written characters   : %llu\n", cpu_structure_pointer->writech);
					__wait_for_return_key_to_proceed();
				}
			}

		/* there are no more statistics to get when "" is returned *
		 * through the 'name' parameter.                           */
		} while (strcmp(name.name, ""));
	}
}
