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

📄 monprof.c

📁 umon bootloader source code, support mips cpu.
💻 C
📖 第 1 页 / 共 2 页
字号:
		}
	}
	if (prof_PcTbl) {
		ushort *sp;
		ulong  *lp;

		sp = (ushort *)prof_PcTbl;
		lp = (ulong *)prof_PcTbl;
		printf("\nPC_PROF stats:\n");
		for(i=0;i<prof_PcTot;i++) {
			switch(prof_PcWidth) {
				case 2:
					if (*sp >= minhit) {
						printf(" %08x    :  %d\n",
							(int)sp + prof_PcDelta,*sp);
						linecount++;
					}
					sp++;
					break;
				case 4:
					if (*lp >= minhit) {
						printf(" %08x    :  %ld\n",
							(int)lp + prof_PcDelta,*lp);
						linecount++;
					}
					lp++;
					break;
			}
			if ((more) && (linecount >= more)) {
				linecount = 0;
				if (More() == 0)
					goto showdone;
			}
		}
	}
showdone:
	putchar('\n');
	if (prof_BadSymCnt)
		printf("%d out-of-range symbols\n",prof_BadSymCnt);
	if (prof_TidOverflow)
		printf("%d tid overflow attempts\n",prof_TidOverflow);
	if (prof_PcOORCnt)
		printf("%d pc out-of-range hits\n",prof_PcOORCnt);
	printf("%d total profiler calls\n",prof_CallCnt);

	if (tfd >= 0)
		tfsclose(tfd,0);
	return;
}

/* prof_FuncConfig():
 * This function builds a table of pdata structures based on the 
 * content of the symbol table.
 * It assumes the file is a list of symbols and addresses listed
 * in ascending address order.
 */
void
prof_FuncConfig(void)
{
	int		tfd, i;
	struct	pdata *pfp;
	char	line[80], *space;

	tfd = prof_GetSymFile();
	if (tfd < 0)
		return;

	prof_FuncTot = 0;
	pfp = prof_FuncTbl;
	
	while(tfsgetline(tfd,line,sizeof(line)-1)) {
		space = strpbrk(line,"\t ");
		if (!space)
			continue;
		*space++ = 0;
		while(isspace(*space))
			space++;
		pfp->data = strtoul(space,0,0);
		pfp->pcount = 0;
		pfp++;
		prof_FuncTot++;
	}
	tfsclose(tfd,0);

	/* Add one last item to the list so that there is an upper limit for
	 * the final symbol in the table:
	 */
	pfp->data = 0xffffffff;
	pfp->pcount = 0;

	/* Test to verify that all symbols are in ascending address order...
	 */
	for (i=0;i<prof_FuncTot;i++) {
		if (prof_FuncTbl[i].data > prof_FuncTbl[i+1].data) {
			printf("Warning: function addresses not in order\n");
			break;
		}
	}
	prof_FuncTot++;
}

/* prof():
 */

char *ProfHelp[] = {
	"Profiler configuration and result display",
	"-[h:m:s:] [operation] [op-specific args]",
#if INCLUDE_VERBOSEHELP
	"Operations:",
	" on                  enable profiler",
	" off                 disable profiler",
	" show                dump stats",
	" init                clear internal tables and runtime stats",
	" call {type pc tid}  call profiler from CLI",
	"                     ('type' can be any combination of 't', 'f' & 'p')",
	" restart             clear runtime stats only",
	" tidcfg {tidtot}     init tid profiler based on number of task ids",
	" funccfg             init function profiler from symtbl file",
	" pccfg {wid add siz} init pc profiler with instruction width (2 or 4)",
	"                     plus size and addr of text area",
	"",
	"Options:",
	" -a{#}        address to use for table",
	" -h{#}        minimum hit count for show",
	" -m{#}        line count for output throttling in show",
	" -s{symfile}  use this file for symbols instead of default",
#endif
	0,
};

int
Prof(int argc,char *argv[])
{
	char	*arg1, *arg2, *arg3, *arg4;
	ulong	address;
	int		i, opt, minhit, ret, more;

	ret = CMD_SUCCESS;
	minhit = 1;
	more = 0;
	address = 0;
	while((opt=getopt(argc,argv,"a:h:m:s:")) != -1) {
		switch(opt) {
		case 'a':
			address = strtoul(optarg,0,0);
			break;
		case 'h':
			minhit = atoi(optarg);
			break;
		case 'm':
			more = atoi(optarg);
			break;
		case 's':
			strncpy(prof_SymFile,optarg,TFSNAMESIZE);
			prof_SymFile[TFSNAMESIZE] = 0;
			break;
		default:
			return(CMD_PARAM_ERROR);
		}
	}

	arg1 = argv[optind];
	arg2 = argv[optind+1];
	arg3 = argv[optind+2];
	arg4 = argv[optind+3];

	if (argc == optind+1) {
		if (!strcmp(arg1,"on")) {
			prof_Enabled = 1;
		}
		else if (!strcmp(arg1,"off")) {
			prof_Enabled = 0;
		}
		else if (!strcmp(arg1,"show")) {
			prof_ShowStats(minhit, more);
		}
		else if (!strcmp(arg1,"init")) {
			prof_BadSymCnt = 0;
			prof_CallCnt = 0;
			prof_TidTally = 0;
			prof_Enabled = 0;
			prof_FuncTot = 0;
			prof_TidTot = 0;
			prof_PcTot = 0;
			prof_FuncTbl = (struct pdata *)0;
			prof_TidTbl = (struct pdata *)0;
			prof_PcTbl = (uchar *)0;
			prof_PcWidth = 0;
			prof_PcDelta = 0;
			prof_SymFile[0] = 0;
		}
		else if (!strcmp(arg1,"restart")) {
			prof_BadSymCnt = 0;
			prof_CallCnt = 0;
			prof_TidTally = 0;
			if (prof_FuncTbl) {
				for(i=0;i<prof_FuncTot;i++) 
					prof_FuncTbl[i].pcount = 0;
			}
			if (prof_TidTbl) {
				for(i=0;i<prof_TidTot;i++) 
					prof_TidTbl[i].pcount = 0;
					prof_TidTbl[i].data = 0;
			}
			if (prof_PcTbl) {
				memset((char *)prof_PcTbl,0,prof_PcTot*prof_PcWidth);
			}
		}
		else if (!strcmp(arg1,"funccfg")) {
			if (prof_FuncTbl) {
				printf("Already configured, run init to re-configure\n");
				return(CMD_FAILURE);
			}
			else if (prof_PcTbl) {
				printf("Can't use PC and FUNC profiling simultaneously\n");
				return(CMD_FAILURE);
			}
			else if (address) {
				prof_FuncTbl = (struct pdata *)address;
			}
			else if (prof_TidTbl) {
				prof_FuncTbl = &prof_TidTbl[prof_TidTot];
			}
			else
				prof_FuncTbl = (struct pdata *)getAppRamStart();
			
			prof_FuncConfig();
		}
		else
			ret = CMD_PARAM_ERROR;
	}
	else if (argc == optind+2) {
		if (!strcmp(arg1,"tidcfg")) {
			if (prof_TidTbl) {
				printf("Already configured, run init to re-configure\n");
				return(CMD_FAILURE);
			}
			else if (address) {
				prof_TidTbl = (struct pdata *)address;
			}
			else if (prof_FuncTbl) {
				prof_TidTbl = &prof_FuncTbl[prof_FuncTot];
			}
			else if (prof_PcTbl) {
				prof_TidTbl = (struct pdata *)&prof_PcTbl[prof_PcTot];
			}
			else
				prof_TidTbl = (struct pdata *)getAppRamStart();
			prof_TidTot = strtoul(arg2,0,0);
			for(i=0;i<prof_TidTot;i++) {
				prof_TidTbl[i].data = 0;
				prof_TidTbl[i].pcount = 0;
			}
		}
		else
			ret = CMD_PARAM_ERROR;
	}
	else if (argc == optind+4) {
		if (!strcmp(arg1,"call")) {
			struct	monprof	mp;

			mp.type = 0;

			if (strchr(arg2,'f'))
				mp.type |= MONPROF_FUNCLOG;
			if (strchr(arg2,'p'))
				mp.type |= MONPROF_PCLOG;
			if (strchr(arg2,'t'))
				mp.type |= MONPROF_TIDLOG;

			mp.pc = strtoul(arg3,0,0);
			mp.tid = strtoul(arg4,0,0);

			profiler(&mp);
		}
		else if (!strcmp(arg1,"pccfg")) {
			int size;

			if (prof_PcTbl) {
				printf("Already configured, run init to re-configure\n");
				return(CMD_FAILURE);
			}
			else if (prof_FuncTbl) {
				printf("Can't use PC and FUNC profiling simultaneously\n");
				return(CMD_FAILURE);
			}
			else if (address) {
				prof_PcTbl = (uchar *)address;
			}
			else if (prof_TidTbl) {
				prof_PcTbl = (uchar *)&prof_TidTbl[prof_TidTot];
			}
			else
				prof_PcTbl = (uchar *)getAppRamStart();
			prof_PcWidth = strtol(arg2,0,0);	/* instruction width */
			prof_PcTxtBase = strtol(arg3,0,0);	/* address of .text */
			size = strtol(arg4,0,0);			/* size of .text */
			prof_PcTxtEnd = prof_PcTxtBase + size;
			prof_PcTot = size / prof_PcWidth;
			prof_PcDelta = (ulong)prof_PcTxtBase - (ulong)prof_PcTbl;
			memset((char *)prof_PcTbl,0,prof_PcTot*prof_PcWidth);

		}
		else
			ret = CMD_PARAM_ERROR;
	}
	else
		ret = CMD_PARAM_ERROR;
		
	return(ret);
}
#else

void
profiler(struct monprof *mpp)
{
}

#endif

⌨️ 快捷键说明

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