/* $Id: lkst_mod_event_count_read.c,v 1.7 2002/10/16 04:18:16 ke-hata Exp $ */
/* testtools/lkst_mod_event_count_read.c */

/************************************************************
 *
 * COPYRIGHT (C) HITACHI,LTD. 2001-2002 ALL RIGHTS RESERVED.
 * WRITTEN BY HITACHI SYSTEMS DEVELOPMENT LABORATORY,
 *            HITACHI CENTRAL RESEARCH LABORATORY.
 *
 * Created by K.SERIZAWA <serizawa@sdl.hitachi.co.jp>
 *
 ************************************************************/


#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <linux/lkst_buffer.h>
  /* ugly fix to avoid conflict. */
#define CMD_LKSTDUMP
#define __KERNEL__
#include <linux/lkst_private.h>	/* for LKST_ETYPE_VERIFY() */
#include <string.h>		/* for strerror(),memset() */

				/* Array of mnemonics of event types */
#define LKST_ETYPE_DEF_MNEMONICS

#include <linux/lkst_events.h>

struct lkst_log_record buffer[LKST_MASKSET_ID_MAX*2+1];
struct lkst_log_record buffer_merged[LKST_MASKSET_ID_MAX*2+1]={0};

int main(int argc, char** argv)
{
	int retval;
	int fd;
	int cpu;
	int iCnt, max_count;
	unsigned int	*pArgs, *pArgs_merged;
	struct lkst_log_buffer lbuffer;
	unsigned int event_type, event_count_sum=0, time_min=0xffffffff, time_max=0;
	struct lkst_status_param param;

	lbuffer.read_size = LKST_MASKSET_ID_MAX*sizeof(struct lkst_log_record)*2;

	lbuffer.buffer = buffer;

	if (( fd = open("/dev/lkst" ,O_RDONLY)) < 0){
		perror("open");
		exit (1);
	}

			/* trc_status */
	if (retval = ioctl(fd, LKST_IOC_TRC_STATUS, &param)) {
		perror("ioctl(LKST_IOC_TRC_STATUS)");
		exit (1);
	}

	for (cpu=0; cpu < 32; cpu++) {
		lbuffer.id = param.current_buffer_id[cpu];
		if (lbuffer.id >= LKST_BUFFER_ID_VOID) break;

		retval = ioctl(fd, LKST_IOC_BUFFER_READ, &lbuffer); /* buff read */
#if DEBUG
		printf("ioctl retval=%d result_read_size=%d id=%d\n", retval,lbuffer.result_read_size, lbuffer.id);

#endif /* DEBUG */

		if (retval) fprintf (stderr, "ioctl(LKST_IOC_BUFFER_READ) error: %s\n", strerror(retval));

#if DEBUG
		if (retval) exit();
#endif /* DEBUG */

		max_count = lbuffer.result_read_size / sizeof(struct lkst_log_record);

		for (iCnt = 0; iCnt < max_count; iCnt++) {
			event_type = buffer[iCnt].posix.log_event_type;
			if (event_type == LKST_ETYPE_LKST_OVWRTN_REC)
				event_type = (int)(buffer[iCnt].log_arg4>>32);
			if ((buffer[iCnt].posix.log_recid)&&
			    (LKST_ETYPE_VERIFY(event_type))) {
				buffer_merged[iCnt].posix.log_event_type
					= event_type;
				buffer_merged[iCnt].posix.log_recid
					= buffer[iCnt].posix.log_recid;
				pArgs_merged = (unsigned int*)&buffer_merged[iCnt].log_arg1;
				pArgs = (unsigned int*)&buffer[iCnt].log_arg1;
				if (pArgs[4]>time_max) time_max = pArgs[4];
				if (pArgs[4]<time_min) time_min = pArgs[4];
				event_count_sum += pArgs[0];
				pArgs_merged[0] += pArgs[0];
				if (pArgs_merged[4]<pArgs[4]) pArgs_merged[4] = pArgs[4];
#if DEBUG
			printf("0x%08x:\t%10u\t10.05g\n", 
			       buffer_merged[iCnt].posix.log_event_type,
			       pArgs[4]);
#endif /* DEBUG */
			}
		}
	}
	if (time_max == time_min) time_max++;
	printf("        %25s:\t%10s\t%10s\n", "event_type", "count", "count/msec");
	for (iCnt = 0; iCnt < max_count; iCnt++) {
		event_type = buffer_merged[iCnt].posix.log_event_type;
#if 0 //TODO
		if (event_type == LKST_ETYPE_LKST_OVWRTN_REC) {
			pArgs = (unsigned int*)&buffer_merged[iCnt].log_arg1;
		printf("  0x%08x 0x%08x 0x%08x 0x%08x \\\n"
		       "  0x%08x 0x%08x 0x%08x 0x%08x \\\n\n",
		       pArgs[0], pArgs[1], pArgs[2], pArgs[3], 
		       pArgs[4], pArgs[5], pArgs[6], pArgs[7]);

			event_type = (int)(buffer_merged[iCnt].log_arg4>>32);
		}
#endif //0 //TODO
		if ((buffer_merged[iCnt].posix.log_recid)&&
		    (LKST_ETYPE_VERIFY(event_type))) {
			pArgs = (unsigned int*)&buffer_merged[iCnt].log_arg1;
			printf("%25s(0x%04x):\t%10u\t%10.05g\n", 
			       lkst_event_type_mnemonics[event_type],
			       event_type,
			       pArgs[0],
			       (double) pArgs[0]/((time_max - time_min)*10));
		}
	}
	printf ("  Total time[s] = %10.04g\n", (time_max - time_min)/100.0);
	printf ("  Total events  = %10u\n", event_count_sum);
	printf ("  rate [n/msec] = %10.05g\n",
		event_count_sum/(double)((time_max - time_min)*10));
}
