gmonfile.c

来自「kaffe Java 解释器语言,源码,Java的子集系统,开放源代码」· C语言 代码 · 共 302 行

C
302
字号
/* * gmonFile.c * gmon_out file handling routines * * Copyright (c) 2000 University of Utah and the Flux Group. * All rights reserved. * * This file is licensed under the terms of the GNU Public License. * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * Contributed by the Flux Research Group, Department of Computer Science, * University of Utah, http://www.cs.utah.edu/flux/ */#if defined(KAFFE_XPROFILER)#include <string.h>#include <stdarg.h>#include <stdlib.h>#include <assert.h>#include <sys/types.h>#include <sys/gmon.h>#include "kaffe/jmalloc.h"#include "gmonFile.h"#define min(x, y) ((x < y) ? x : y)struct gmon_file *createGmonFile(char *filename){	struct gmon_file *retval = 0;	FILE *file;	if( (file = fopen(filename, "w")) )	{		struct gmon_hdr gh;				/* Write out the header */		memcpy(gh.cookie, GMON_MAGIC, sizeof(gh.cookie));		*((int *)gh.version) = GMON_VERSION;		bzero(&gh.spare, sizeof(gh.spare));		fwrite(&gh, sizeof(struct gmon_hdr), 1, file);		if( !ferror(file) &&		    (retval = (struct gmon_file *)		     KMALLOC(sizeof(struct gmon_file))) )		{			retval->gf_name = filename;			retval->gf_file = file;			retval->gf_low = 0;			retval->gf_addr = 0;			retval->gf_high = 0;			/* Start out writing records */			retval->gf_state = GFS_RECORD;		}		else		{			fclose(file);			remove(filename);		}	}	return( retval );}void deleteGmonFile(struct gmon_file *gf){	if( gf )	{		fclose(gf->gf_file);		/* Delete the file if there was an error in writing */		if( gf->gf_state == GFS_ERROR )			remove(gf->gf_name);		KFREE(gf);	}}long writeGmonRecord(struct gmon_file *gf, int tag, ...){	struct gmon_cg_arc_record cga;	long retval = 0, rewrite = -1;	struct gmon_hist_hdr ghh;	unsigned char hdr_tag;	va_list args;	va_start(args, tag);	/* Walk over the tag list getting whatever info we care about */	while( tag != GRA_DONE )	{		switch( tag )		{		case GRA_Type:			hdr_tag = va_arg(args, int);			/* Initialize the record structure */			switch(hdr_tag)			{			case GMON_TAG_TIME_HIST:				bzero(ghh.low_pc, sizeof(ghh.low_pc));				bzero(ghh.high_pc, sizeof(ghh.high_pc));				bzero(ghh.hist_size, sizeof(ghh.hist_size));				*((int *)ghh.prof_rate) = 100;				strcpy(ghh.dimen, "seconds");				ghh.dimen_abbrev = 's';				break;			case GMON_TAG_CG_ARC:				bzero(cga.from_pc, sizeof(cga.from_pc));				bzero(cga.self_pc, sizeof(cga.self_pc));				bzero(cga.count, sizeof(cga.count));				break;			}			break;		case GRA_Rewrite:			rewrite = va_arg(args, long);			break;			/* Histogram attributes */		case GRA_LowPC:			{				char *lowpc = va_arg(args, char *);								*((char **)ghh.low_pc) = lowpc;				gf->gf_low = lowpc;			}			break;		case GRA_HighPC:			*((char **)ghh.high_pc) = va_arg(args, char *);			break;		case GRA_PCSize:			*((char **)ghh.high_pc) = *((char **)ghh.low_pc) +				va_arg(args, int);			break;		case GRA_Dimension:			strcpy(ghh.dimen, va_arg(args, char *));			break;		case GRA_DimensionAbbrev:			ghh.dimen_abbrev = va_arg(args, int);			break;		case GRA_ProfilingRate:			*((int *)ghh.prof_rate) = va_arg(args, int);			break;			/* Call graph attributes */		case GRA_FromPC:			*((char **)cga.from_pc) = va_arg(args, char *);			break;		case GRA_SelfPC:			*((char **)cga.self_pc) = va_arg(args, char *);			break;		case GRA_Count:			*((int *)cga.count) = va_arg(args, int);			break;		default:			break;		}		tag = va_arg(args, int);	}	if( rewrite == -1 )	{		assert(gf->gf_state == GFS_RECORD);		/* Write out the tag */		fwrite(&hdr_tag, sizeof(hdr_tag), 1, gf->gf_file);	}	if( !ferror(gf->gf_file) )	{		/* Write out the actual record */		switch(hdr_tag)		{		case GMON_TAG_TIME_HIST:			*((int *)ghh.hist_size) = (*((char **)ghh.high_pc) -						   *((char **)ghh.low_pc)) /				HISTFRACTION;			gf->gf_high = *((char **)ghh.high_pc);			retval = ftell(gf->gf_file);			/* If this is a rewrite, seek back to the record */			if( rewrite != -1 )				fseek(gf->gf_file, rewrite, SEEK_SET);			fwrite(&ghh, sizeof(ghh), 1, gf->gf_file);			if( !ferror(gf->gf_file) )			{				gf->gf_state = GFS_SAMPLES;				/*				 * If it was a rewrite, seek forward to where				 * we were				 */				if( rewrite != -1 )				{					/*					 * If the high was changed we might					 * need to switch states.					 */					if( gf->gf_addr == gf->gf_high )						gf->gf_state = GFS_RECORD;					fseek(gf->gf_file, retval, SEEK_SET);				}			}			else			{				gf->gf_state = GFS_ERROR;				retval = 0;			}			gf->gf_addr = gf->gf_low;			break;		case GMON_TAG_CG_ARC:			retval = ftell(gf->gf_file);			/* If this is a rewrite seek back to the record */			if( rewrite != -1 )				fseek(gf->gf_file, rewrite, SEEK_SET);			fwrite(&cga, sizeof(cga), 1, gf->gf_file);			if( !ferror(gf->gf_file) )			{				/*				 * If it was a rewrite, seek forward to where				 * we were				 */				if( rewrite != -1 )					fseek(gf->gf_file, retval, SEEK_SET);			}			else			{				gf->gf_state = GFS_ERROR;				retval = 0;			}			break;		default:			break;		}	}	else	{		gf->gf_state = GFS_ERROR;	}	va_end(args);	return( retval );}int writeGmonSamples(struct gmon_file *gf, char *addr, short *bins, int size){	int retval = 1;	assert(gf->gf_state == GFS_SAMPLES);	/* Fill any gaps between the current address and the one we're given */	retval = fillGmonSamples(gf, addr);	if( retval )	{		fwrite(bins, sizeof(short), size, gf->gf_file);		if( !ferror(gf->gf_file) )		{			/* Increment the current sample index */			gf->gf_addr += (size * HISTFRACTION);			if( gf->gf_addr == gf->gf_high )			{				/* Switch back to writing records */				gf->gf_state = GFS_RECORD;			}			else			{				assert( gf->gf_addr < gf->gf_high );			}		}		else		{			gf->gf_state = GFS_ERROR;			retval = 0;		}	}	else		gf->gf_state = GFS_ERROR;	return( retval );}int fillGmonSamples(struct gmon_file *gf, char *addr){	short filler = 0;	int retval = 1;		/* If there was a gap in writing the samples then fill it with zeros */	for( ; (gf->gf_addr < addr) && retval; gf->gf_addr += HISTFRACTION )	{		fwrite(&filler, sizeof(filler), 1, gf->gf_file);	}	if( !ferror(gf->gf_file) )	{		/* Switch back to writing records */		if( gf->gf_addr == gf->gf_high )			gf->gf_state = GFS_RECORD;	}	else		gf->gf_state = GFS_ERROR;	return( retval );}int gmonSampleWalker(void *handle, char *addr, short *bins, int size){	struct gmon_file *gf = handle;	return( !writeGmonSamples(gf, addr, bins, size) );}#endif /* KAFFE_XPROFILER */

⌨️ 快捷键说明

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