rvprftrace.c

来自「h.248协议源码」· C语言 代码 · 共 239 行

C
239
字号
/******************************************************************************
Filename    : rvprftrace.c
Description : Performance Trace objects
			  Note: high precision time functions implemented only for Windows
			  No thread safe
******************************************************************************
                Copyright (c) 1999 RADVision Inc.
************************************************************************
NOTICE:
This document contains information that is proprietary to RADVision LTD.
No part of this publication may be reproduced in any form whatsoever 
without written prior approval by RADVision LTD..

RADVision LTD. reserves the right to revise this publication and make 
changes without obligation to notify any person of such revisions or 
changes.
******************************************************************************
$Revision:1.0$
$Date:9/15/00$
$Author:Dan Elbert$
******************************************************************************/

#ifdef RV_PRFTRACE_ON

#include <stdio.h>
#include <string.h>
#include <windows.h>

#include "rvmem.h"
#include "rvprftrace.h"


/* Private functions */
void rvPrfTraceNormalize(RvPrfTrace * p);
__int64 rvPrfTraceGetFrame(void);
__int64 rvPrfTraceGetStamp(void);
char* rvPrfTraceGetCheckpointName(int nameF, char *lpName,void * userdata);


static void  rvPrfTraceOutput(RvPrfTrace * p) {
	int i,j;		
	FILE * fp;
	char filename[255];

	for(i=0;i<p->chkpnum;i++) {
		/* Open file */
		strcpy(filename,rvPrfTraceGetCheckpointName(i,0,p));
		strcat(filename,".txt");
		if( (fp=fopen(filename,"a")) == NULL )
			continue;
		fprintf(fp,"%-15s%-15s\n",rvPrfTraceGetCheckpointName(i,0,p),rvPrfTraceGetCheckpointName(i,0,p));
		fprintf(fp,"%-12s%-3s%-15s\n","Total_time"," ","Net_time");
		for(j=0;j<p->max;j++) {
			if(i==p->trace_array[j].chkp_id) {
				fprintf(fp,"%-15u",p->trace_array[j].elapsed);
				fprintf(fp,"%-15u\n",p->trace_array[j].net);
			}
		}
		fclose(fp);
	}
}

static void  rvPrfTraceOutputAvg(RvPrfTrace * p) {
	int i;	
	double total = 0;
	FILE * fp;
	if( (fp=fopen("prf_avg.txt","a")) == NULL )
		return;

	for(i=0;i<p->chkpnum;i++) {
		fprintf(fp,"%-30s: %-20f mcsec, %-10u calls\n",
			rvPrfTraceGetCheckpointName(i,0,p),
			p->checkpoint_avg[i].avg_time,p->checkpoint_avg[i].count);
		total+=p->checkpoint_avg[i].avg_time;
	}
	fprintf(fp,"Total average time: %-20f mcsecs\n",total);
	fprintf(fp,"\n");
	fclose(fp);
}


void  rvPrfTraceStart(RvPrfTrace * p, int checkpoint_id) {
	if(p->trace==rvTrue) {
		/*printf("Start function %s,line %d\n",rvPrfTraceGetCheckpointName(checkpoint_id,0,p),p->next_element);*/
		p->trace_array[p->next_element].chkp_id = checkpoint_id;
		p->trace_array[p->next_element].start = rvPrfTraceGetStamp();
		p->trace_array[p->next_element].end = 0;
		/*printf("Start time: %lu\n",p->trace_array[p->next_element].start);*/
		/* Push the element index in the stack */
		p->call_stack[p->stack_idx++] = p->next_element;
		/* Increment the next element */
		p->next_element++;
	}
}


static void rvPrfTraceProcess(RvPrfTrace * p) {
	rvPrfTraceNormalize(p);
	p->max = p->next_element;
	p->next_element = 0;
	p->stack_idx = 0;
	(p->process)(p);
}

void  rvPrfTraceStop(RvPrfTrace * p) {
	if(p->trace==rvTrue) {
		/* Pop the element index from the stack */
		int elem = 	p->call_stack[--p->stack_idx];
		p->trace_array[elem].end = rvPrfTraceGetStamp();

		/*printf("Stop function %s,line %d\n",rvPrfTraceGetCheckpointName(p->trace_array[elem].chkp_id,0,p),elem);*/
		/*printf("End time: %lu\n",p->trace_array[elem].end);*/

		/* Full array */
		if( (p->next_element+RV_PRFTRACE_MAX_CALLS*10)>=RV_PRFTRACE_MAX_ELEM) {
			if(p->stack_idx==0)
				rvPrfTraceProcess(p);
		}
	}
}

/* Default callback to retrieve function name */
static char* rvPrfTraceGetCheckpointName(int nameF, char* lpName,void * userdata) {
	RvPrfTrace *  p = (RvPrfTrace*)userdata;
	return p->checkpoint_arr[nameF];
}


/* Arguments
   checkpoint_arr - pointer to array with function names (mapped to function index)
   num_of_checkpoints - number of functions being traced
   process - function to be called when the array is full, to process and output results
   process_final - final processing, called when trace is destructed
*/
void  rvPrfTraceConstruct(RvPrfTrace * p,char** checkpoint_arr,int num_of_checkpoints) { 
	p->next_element = 0;
	p->stack_idx = 0;
	p->checkpoint_arr = checkpoint_arr;
	p->chkpnum = num_of_checkpoints;
	p->checkpoint_avg = rvMemAlloc(sizeof(RvPrfTraceChkpAvg)*num_of_checkpoints);
	memset((void*)p->checkpoint_avg,0,sizeof(RvPrfTraceChkpAvg)*num_of_checkpoints);
	p->get_chkname = rvPrfTraceGetCheckpointName;
	p->process = rvPrfTraceOutput;
	p->process_final = rvPrfTraceOutputAvg;
	p->trace = rvTrue;
}

void  rvPrfTraceDestruct(RvPrfTrace * p) {
	rvPrfTraceProcess(p);
	(p->process_final)(p);
	rvMemFree(p->checkpoint_avg);
}

void rvPrfTraceEnable(RvPrfTrace * p) {
	p->trace = rvTrue;
}

void rvPrfTraceDisable(RvPrfTrace * p) {
	p->trace = rvFalse;
}

static __int64  rvPrfTraceGetFrame(void) {
   LARGE_INTEGER lpFrequency;
   QueryPerformanceFrequency( &lpFrequency );
   return lpFrequency.QuadPart;

}

static __int64 rvPrfTraceGetStamp(void) {
 LARGE_INTEGER  lpPerformanceCount;
 QueryPerformanceCounter( &lpPerformanceCount );
 return  lpPerformanceCount.QuadPart ;
}

/* Adjust the net time spent in entry i, by substracting the time spent in 
   functions called from the main function. Recursive */
static int AdjustNetTime(RvPrfTrace * p,int i) {
	int next,j=i+1;

	while(p->trace_array[i].end > p->trace_array[j].start
			&& j < p->next_element ) {
		next = AdjustNetTime(p,j);
		p->trace_array[i].net-=p->trace_array[j].elapsed;
		j = next;
	}
	return j;
}

static void rvPrfTraceNormalize(RvPrfTrace * p) {
	int i,f;
	__int64 result;
	__int64 freqF;
	double  freq;
	double * acc = rvMemAlloc(sizeof(double)*p->chkpnum); /* Accumulated time */
	int	   * fcnt = rvMemAlloc(sizeof(int)*p->chkpnum);

	freqF = rvPrfTraceGetFrame();
	freq = (long double)freqF / 1000000;

	memset((void*)acc,0,sizeof(double)*p->chkpnum);
	memset((void*)fcnt,0,sizeof(int)*p->chkpnum);

	/* Calculate elapsed time */
	for(i = 0; i < p->next_element; i++)
	{
		result = p->trace_array[i].end - p->trace_array[i].start;
		if(p->trace_array[i].end && p->trace_array[i].start) {
			p->trace_array[i].elapsed = result / (__int64)freq;
			p->trace_array[i].net = p->trace_array[i].elapsed;
		}
		else
			p->trace_array[i].elapsed = p->trace_array[i].net = 0;
	}

	/* Substract from the time the time actually spent in another function */
	for(i = 0; i < p->next_element; ) {
		i  = AdjustNetTime(p,i);
	}

	/* Calculate running average */
	for(i = 0; i < p->next_element; i++) {
		f = (int)p->trace_array[i].chkp_id;
		acc[f]+=p->trace_array[i].net;
		fcnt[f]++;
	}
	for(i=0;i<p->chkpnum;i++) {
		if(fcnt[i])  {
			p->checkpoint_avg[i].avg_time = ( p->checkpoint_avg[i].avg_time*p->checkpoint_avg[i].count + 
									   acc[i] ) / (p->checkpoint_avg[i].count+fcnt[i]);
			p->checkpoint_avg[i].count+=fcnt[i];
		}
	}

	rvMemFree(acc);
	rvMemFree(fcnt);
}	

#endif /* RV_PRFTRACE_ON */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?