⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pmon.c

📁 早期freebsd实现
💻 C
字号:
/*- * Copyright (c) 1980, 1993 *	The Regents of the University of California.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#ifndef lintstatic char sccsid[] = "@(#)pmon.c	8.1 (Berkeley) 6/6/93";#endif /* not lint *//* * pxp - Pascal execution profiler * * Bill Joy UCB * Version 1.2 January 1979 */#include "0.h"/* * Profile counter processing cluster * * This file contains all routines which do the hard work in profiling. * * The first group of routines (getit, getpmon, getcore, and pmread) * deal with extracting data from the pmon.out and (with more difficulty) * core files. * * The routines cnttab and prttab collect counters for * and print the summary table respectively. * * The routines "*cnt*" deal with manipulation of counters, * especially the "current" counter px. */STATIC	struct pxcnt px;/* * Table to record info * for procedure/function summary */STATIC	struct pftab {	long	pfcnt;	short	pfline;	char	*pfname;	short	pflev;} *zpf;/* * Global variables */STATIC	long *zbuf; 	/* Count buffer */STATIC	short zcnt;	/* Number of counts */STATIC	short zpfcnt;	/* Number of proc/funcs's */STATIC	short gcountr;	/* Unique name generator */STATIC	short zfil;	/* I/o unit for count data reads */STATIC	short lastpf;	/* Total # of procs and funcs for consistency chk */getit(fp)	register char *fp;{	if (core)		getcore(fp);	else		getpmon(fp);}/* * Setup monitor data buffer from pmon.out * style file whose name is fp. */getpmon(fp)	char *fp;{	register char *cp;	short garbage;	zfil = open(fp, 0);	if (zfil < 0) {		perror(fp);		pexit(NOSTART);	}	if (pmread() < 0 || read(zfil, &garbage, 1) == 1) {		Perror(fp, "Bad format for pmon.out style file");		exit(1);	}	close(zfil);	return;}STATIC	char nospcm[]	= "Not enough memory for count buffers\n";pmnospac(){	write(2, nospcm, sizeof nospcm);	pexit(NOSTART);}/* * Structure of the first few * items of a px core dump. */STATIC	struct info {	char	*off;		/* Self-reference for pure text */	short	type;		/* 0 = non-pure text, 1 = pure text */	char	*bp;		/* Core address of pxps struct */} inf;/* * First few words of the px * information structure. */STATIC	struct pxps {	char	*buf;	short	cnt;} pxp;getcore(fp)	char *fp;{	write(2, "-c: option not supported\n", sizeof("-c: option not supported\n"));	pexit(ERRS);/*	short pm;	zfil = open(fp, 0);	if (zfil < 0) {		perror(fp);		pexit(NOSTART);	}	if (lseek(zfil, 02000, 0) < 0)		goto format;	if (read(zfil, &inf, sizeof inf) < 0)		goto format;	if (inf.type != 0 && inf.type != 1)		goto format;	if (inf.type)		inf.bp -= inf.off;	if (lseek(zfil, inf.bp + 02000, 0) < 0)		goto format;	if (read(zfil, &pxp, sizeof pxp) != sizeof pxp)		goto format;	if (pxp.buf == NIL) {		Perror(fp, "No profile data in file");		exit(1);	}	if (inf.type)		pxp.buf -= inf.off;	if (lseek(zfil, pxp.buf + 02000, 0) < 0)		goto format;	if (pmread() < 0)		goto format;	close(zfil);	return;format:	Perror(fp, "Not a Pascal system core file");	exit(1);*/}pmread(){	register i;	register char *cp;	struct {		long	no;		long	tim;		long	cntrs;		long	rtns;	} zmagic;	if (read(zfil, &zmagic, sizeof zmagic) != sizeof zmagic)		return (-1);	if (zmagic.no != 0426)		return (-1);	ptvec = zmagic.tim;	zcnt = zmagic.cntrs;	zpfcnt = zmagic.rtns;	cp = zbuf = pcalloc(i = (zcnt + 1) * sizeof *zbuf, 1);	if (cp == NULL)		pmnospac();	cp = zpf = pcalloc(zpfcnt * sizeof *zpf, 1);	if (cp == NULL)		pmnospac();	i -= sizeof(zmagic);	if (read(zfil, zbuf + (sizeof(zmagic) / sizeof(*zbuf)), i) != i)		return (-1);	zbuf++;	return (0);}cnttab(s, no)	char *s;	short no;{	register struct pftab *pp;	lastpf++;	if (table == 0)		return;	if (no == zpfcnt)		cPANIC();	pp = &zpf[no];	pp->pfname = s;	pp->pfline = line;	pp->pfcnt = nowcnt();	pp->pflev = cbn;}prttab(){	register i, j;	register struct pftab *zpfp;	if (profile == 0 && table == 0)		return;	if (cnts != zcnt || lastpf != zpfcnt)		cPANIC();	if (table == 0)		return;	if (profile)		printf("\f\n");	header();	printf("\n\tLine\t   Count\n\n");	zpfp = zpf;	for (i = 0; i < zpfcnt; i++) {		printf("\t%4d\t%8ld\t", zpfp->pfline, zpfp->pfcnt);		if (!justify)			for (j = zpfp->pflev * unit; j > 1; j--)				putchar(' ');		printf("%s\n", zpfp->pfname);		zpfp++;	}}nowcntr(){	return (px.counter);}long nowcnt(){	return (px.ntimes);}long cntof(pxc)	struct pxcnt *pxc;{	if (profile == 0 && table == 0)		return;	return (pxc->ntimes);}setcnt(l)	long l;{	if (profile == 0 && table == 0)		return;	px.counter = --gcountr;	px.ntimes = l;	px.gos = gocnt;	px.printed = 0;}savecnt(pxc)	register struct pxcnt *pxc;{	if (profile == 0 && table == 0)		return;	pxc->ntimes = px.ntimes;	pxc->counter = px.counter;	pxc->gos = px.gos;	pxc->printed = 1;}rescnt(pxc)	register struct pxcnt *pxc;{	if (profile == 0 && table == 0)		return;	px.ntimes = pxc->ntimes;	px.counter = pxc->counter;	px.gos = gocnt;	px.printed = pxc->printed;	return (gocnt != pxc->gos);}getcnt(){	if (profile == 0 && table == 0)		return;	if (cnts == zcnt)		cPANIC();	px.counter = cnts;	px.ntimes = zbuf[cnts];	px.gos = gocnt;	px.printed = 0;	++cnts;}unprint(){	px.printed = 0;}/* * Control printing of '|' * when profiling. */STATIC	char	nobar;baroff(){	nobar = 1;}baron(){	nobar = 0;}/* * Do we want cnt and/or '|' on this line ? *	1 = count and '|' *	0 = only '|' *     -1 = spaces only */shudpcnt(){	register i;	if (nobar)		return (-1);	i = px.printed;	px.printed = 1;	return (i == 0);}STATIC	char mism[]	= "Program and counter data do not correspond\n";cPANIC(){	printf("cnts %d zcnt %d, lastpf %d zpfcnt %d\n",		cnts, zcnt, lastpf, zpfcnt);	flush();	write(2, mism, sizeof mism);	pexit(ERRS);}

⌨️ 快捷键说明

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