📄 proflfun.c
字号:
/*******************************************************/
/* "C" Language Integrated Production System */
/* */
/* CLIPS Version 6.24 06/02/06 */
/* */
/* CONSTRUCT PROFILING FUNCTIONS MODULE */
/*******************************************************/
/*************************************************************/
/* Purpose: Contains the code for profiling the amount of */
/* time spent in constructs and user defined functions. */
/* */
/* Principal Programmer(s): */
/* Gary D. Riley */
/* */
/* Contributing Programmer(s): */
/* */
/* Revision History: */
/* 6.23: Modified OutputProfileInfo to allow a before */
/* and after prefix so that a string buffer does */
/* not need to be created to contain the entire */
/* prefix. This allows a buffer overflow problem */
/* to be corrected. DR0857. */
/* */
/* 6.24: Renamed BOOLEAN macro type to intBool. */
/* */
/* Added pragmas to remove compilation warnings. */
/* */
/* Corrected code to remove run-time program */
/* compiler warnings. */
/* */
/*************************************************************/
#define _PROFLFUN_SOURCE_
#include "setup.h"
#if PROFILING_FUNCTIONS
#include "argacces.h"
#include "classcom.h"
#include "dffnxfun.h"
#include "envrnmnt.h"
#include "extnfunc.h"
#include "genrccom.h"
#include "genrcfun.h"
#include "memalloc.h"
#include "msgcom.h"
#include "router.h"
#include "sysdep.h"
#include "proflfun.h"
#include <string.h>
#define NO_PROFILE 0
#define USER_FUNCTIONS 1
#define CONSTRUCTS_CODE 2
#define OUTPUT_STRING "%-40s %7ld %15.6f %8.2f%% %15.6f %8.2f%%\n"
/***************************************/
/* LOCAL INTERNAL FUNCTION DEFINITIONS */
/***************************************/
static intBool OutputProfileInfo(void *,char *,struct constructProfileInfo *,
char *,char *,char *,char **);
static void OutputUserFunctionsInfo(void *);
static void OutputConstructsCodeInfo(void *);
#if (! RUN_TIME)
static void ProfileClearFunction(void *);
#endif
/******************************************************/
/* ConstructProfilingFunctionDefinitions: Initializes */
/* the construct profiling functions. */
/******************************************************/
globle void ConstructProfilingFunctionDefinitions(
void *theEnv)
{
struct userDataRecord profileDataInfo = { 0, CreateProfileData, DeleteProfileData };
AllocateEnvironmentData(theEnv,PROFLFUN_DATA,sizeof(struct profileFunctionData),NULL);
memcpy(&ProfileFunctionData(theEnv)->ProfileDataInfo,&profileDataInfo,sizeof(struct userDataRecord));
ProfileFunctionData(theEnv)->LastProfileInfo = NO_PROFILE;
ProfileFunctionData(theEnv)->PercentThreshold = 0.0;
ProfileFunctionData(theEnv)->OutputString = OUTPUT_STRING;
#if ! RUN_TIME
EnvDefineFunction2(theEnv,"profile",'v', PTIEF ProfileCommand,"ProfileCommand","11w");
EnvDefineFunction2(theEnv,"profile-info",'v', PTIEF ProfileInfoCommand,"ProfileInfoCommand","01w");
EnvDefineFunction2(theEnv,"profile-reset",'v', PTIEF ProfileResetCommand,"ProfileResetCommand","00");
EnvDefineFunction2(theEnv,"set-profile-percent-threshold",'d',
PTIEF SetProfilePercentThresholdCommand,
"SetProfilePercentThresholdCommand","11n");
EnvDefineFunction2(theEnv,"get-profile-percent-threshold",'d',
PTIEF GetProfilePercentThresholdCommand,
"GetProfilePercentThresholdCommand","00");
ProfileFunctionData(theEnv)->ProfileDataID = InstallUserDataRecord(theEnv,&ProfileFunctionData(theEnv)->ProfileDataInfo);
EnvAddClearFunction(theEnv,"profile",ProfileClearFunction,0);
#endif
}
/**********************************/
/* CreateProfileData: Allocates a */
/* profile user data structure. */
/**********************************/
globle void *CreateProfileData(
void *theEnv)
{
struct constructProfileInfo *theInfo;
theInfo = (struct constructProfileInfo *)
genalloc(theEnv,sizeof(struct constructProfileInfo));
theInfo->numberOfEntries = 0;
theInfo->childCall = FALSE;
theInfo->startTime = 0.0;
theInfo->totalSelfTime = 0.0;
theInfo->totalWithChildrenTime = 0.0;
return(theInfo);
}
/**************************************/
/* DeleteProfileData: */
/**************************************/
globle void DeleteProfileData(
void *theEnv,
void *theData)
{
genfree(theEnv,theData,sizeof(struct constructProfileInfo));
}
/**************************************/
/* ProfileCommand: H/L access routine */
/* for the profile command. */
/**************************************/
globle void ProfileCommand(
void *theEnv)
{
char *argument;
DATA_OBJECT theValue;
if (EnvArgCountCheck(theEnv,"profile",EXACTLY,1) == -1) return;
if (EnvArgTypeCheck(theEnv,"profile",1,SYMBOL,&theValue) == FALSE) return;
argument = DOToString(theValue);
if (! Profile(theEnv,argument))
{
ExpectedTypeError1(theEnv,"profile",1,"symbol with value constructs, user-functions, or off");
return;
}
return;
}
/******************************/
/* Profile: C access routine */
/* for the profile command. */
/******************************/
globle intBool Profile(
void *theEnv,
char *argument)
{
/*======================================================*/
/* If the argument is the symbol "user-functions", then */
/* user-defined functions should be profiled. If the */
/* argument is the symbol "constructs", then */
/* deffunctions, generic functions, message-handlers, */
/* and rule RHS actions are profiled. */
/*======================================================*/
if (strcmp(argument,"user-functions") == 0)
{
ProfileFunctionData(theEnv)->ProfileStartTime = gentime();
ProfileFunctionData(theEnv)->ProfileUserFunctions = TRUE;
ProfileFunctionData(theEnv)->ProfileConstructs = FALSE;
ProfileFunctionData(theEnv)->LastProfileInfo = USER_FUNCTIONS;
}
else if (strcmp(argument,"constructs") == 0)
{
ProfileFunctionData(theEnv)->ProfileStartTime = gentime();
ProfileFunctionData(theEnv)->ProfileUserFunctions = FALSE;
ProfileFunctionData(theEnv)->ProfileConstructs = TRUE;
ProfileFunctionData(theEnv)->LastProfileInfo = CONSTRUCTS_CODE;
}
/*======================================================*/
/* Otherwise, if the argument is the symbol "off", then */
/* don't profile constructs and user-defined functions. */
/*======================================================*/
else if (strcmp(argument,"off") == 0)
{
ProfileFunctionData(theEnv)->ProfileEndTime = gentime();
ProfileFunctionData(theEnv)->ProfileTotalTime += (ProfileFunctionData(theEnv)->ProfileEndTime - ProfileFunctionData(theEnv)->ProfileStartTime);
ProfileFunctionData(theEnv)->ProfileUserFunctions = FALSE;
ProfileFunctionData(theEnv)->ProfileConstructs = FALSE;
}
/*=====================================================*/
/* Otherwise, generate an error since the only allowed */
/* arguments are "on" or "off." */
/*=====================================================*/
else
{ return(FALSE); }
return(TRUE);
}
/******************************************/
/* ProfileInfoCommand: H/L access routine */
/* for the profile-info command. */
/******************************************/
globle void ProfileInfoCommand(
void *theEnv)
{
int argCount;
DATA_OBJECT theValue;
char buffer[512];
/*===================================*/
/* The profile-info command expects */
/* at most a single symbol argument. */
/*===================================*/
if ((argCount = EnvArgCountCheck(theEnv,"profile",NO_MORE_THAN,1)) == -1) return;
/*===========================================*/
/* The first profile-info argument indicates */
/* the field on which sorting is performed. */
/*===========================================*/
if (argCount == 1)
{
if (EnvArgTypeCheck(theEnv,"profile",1,SYMBOL,&theValue) == FALSE) return;
}
/*==================================*/
/* If code is still being profiled, */
/* update the profile end time. */
/*==================================*/
if (ProfileFunctionData(theEnv)->ProfileUserFunctions || ProfileFunctionData(theEnv)->ProfileConstructs)
{
ProfileFunctionData(theEnv)->ProfileEndTime = gentime();
ProfileFunctionData(theEnv)->ProfileTotalTime += (ProfileFunctionData(theEnv)->ProfileEndTime - ProfileFunctionData(theEnv)->ProfileStartTime);
}
/*==================================*/
/* Print the profiling information. */
/*==================================*/
if (ProfileFunctionData(theEnv)->LastProfileInfo != NO_PROFILE)
{
sprintf(buffer,"Profile elapsed time = %g seconds\n",
ProfileFunctionData(theEnv)->ProfileTotalTime);
EnvPrintRouter(theEnv,WDISPLAY,buffer);
if (ProfileFunctionData(theEnv)->LastProfileInfo == USER_FUNCTIONS)
{ EnvPrintRouter(theEnv,WDISPLAY,"Function Name "); }
else if (ProfileFunctionData(theEnv)->LastProfileInfo == CONSTRUCTS_CODE)
{ EnvPrintRouter(theEnv,WDISPLAY,"Construct Name "); }
EnvPrintRouter(theEnv,WDISPLAY,"Entries Time % Time+Kids %+Kids\n");
if (ProfileFunctionData(theEnv)->LastProfileInfo == USER_FUNCTIONS)
{ EnvPrintRouter(theEnv,WDISPLAY,"------------- "); }
else if (ProfileFunctionData(theEnv)->LastProfileInfo == CONSTRUCTS_CODE)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -