Modified: trunk/darkplaces/pr_comp.h
===================================================================
--- trunk/darkplaces/pr_comp.h	2007-10-18 07:09:15 UTC (rev 7646)
+++ trunk/darkplaces/pr_comp.h	2007-10-19 10:51:33 UTC (rev 7647)
@@ -167,6 +167,7 @@
 	double	profile;		// runtime
 	double	builtinsprofile; // cost of builtin functions called by this function
 	double	callcount; // times the functions has been called since the last profile call
+	double  totaltime; // total execution time of this function DIRECTLY FROM THE ENGINE
 
 	int		s_name;
 	int		s_file;			// source file defined in

Modified: trunk/darkplaces/progsvm.h
===================================================================
--- trunk/darkplaces/progsvm.h	2007-10-18 07:09:15 UTC (rev 7646)
+++ trunk/darkplaces/progsvm.h	2007-10-19 10:51:33 UTC (rev 7647)
@@ -288,6 +288,7 @@
 // NOTE: external code has to create and free the mempools but everything else is done by prvm !
 typedef struct prvm_prog_s
 {
+	double              starttime;
 	dprograms_t			*progs;
 	mfunction_t			*functions;
 	char				*strings;
@@ -464,6 +465,7 @@
 
 void PRVM_Profile (int maxfunctions, int mininstructions);
 void PRVM_Profile_f (void);
+void PRVM_CallProfile_f (void);
 void PRVM_PrintFunction_f (void);
 
 void PRVM_PrintState(void);

Modified: trunk/darkplaces/prvm_edict.c
===================================================================
--- trunk/darkplaces/prvm_edict.c	2007-10-18 07:09:15 UTC (rev 7646)
+++ trunk/darkplaces/prvm_edict.c	2007-10-19 10:51:33 UTC (rev 7647)
@@ -1500,6 +1500,7 @@
 	PRVM_GCALL(reset_cmd)();
 	Mem_FreePool(&prog->progs_mempool);
 	memset(prog,0,sizeof(prvm_prog_t));
+	prog->starttime = Sys_DoubleTime();
 }
 
 /*
@@ -2028,6 +2029,7 @@
 	Cmd_AddCommand ("prvm_edicts", PRVM_ED_PrintEdicts_f, "prints all data about all entities in the selected VM (server, client, menu)");
 	Cmd_AddCommand ("prvm_edictcount", PRVM_ED_Count_f, "prints number of active entities in the selected VM (server, client, menu)");
 	Cmd_AddCommand ("prvm_profile", PRVM_Profile_f, "prints execution statistics about the most used QuakeC functions in the selected VM (server, client, menu)");
+	Cmd_AddCommand ("prvm_callprofile", PRVM_CallProfile_f, "prints execution statistics about the most time consuming QuakeC calls from the engine in the selected VM (server, client, menu)");
 	Cmd_AddCommand ("prvm_fields", PRVM_Fields_f, "prints usage statistics on properties (how many entities have non-zero values) in the selected VM (server, client, menu)");
 	Cmd_AddCommand ("prvm_globals", PRVM_Globals_f, "prints all global variables in the selected VM (server, client, menu)");
 	Cmd_AddCommand ("prvm_global", PRVM_Global_f, "prints value of a specified global variable in the selected VM (server, client, menu)");
@@ -2061,6 +2063,7 @@
 		PRVM_ResetProg();
 
 	memset(prog, 0, sizeof(prvm_prog_t));
+	prog->starttime = Sys_DoubleTime();
 
 	prog->error_cmd = Host_Error;
 }

Modified: trunk/darkplaces/prvm_exec.c
===================================================================
--- trunk/darkplaces/prvm_exec.c	2007-10-18 07:09:15 UTC (rev 7646)
+++ trunk/darkplaces/prvm_exec.c	2007-10-19 10:51:33 UTC (rev 7647)
@@ -266,6 +266,43 @@
 }
 
 
+void PRVM_CallProfile ()
+{
+	mfunction_t *f, *best;
+	int i;
+	double max;
+	double sum;
+
+	Con_Printf( "%s Call Profile:\n", PRVM_NAME );
+
+	sum = 0;
+	do
+	{
+		max = 0;
+		best = NULL;
+		for (i=0 ; i<prog->progs->numfunctions ; i++)
+		{
+			f = &prog->functions[i];
+			if (max < f->totaltime)
+			{
+				max = f->totaltime;
+				best = f;
+			}
+		}
+		if (best)
+		{
+			sum += best->totaltime;
+			Con_Printf("%9.4f %s\n", best->totaltime, PRVM_GetString(best->s_name));
+			best->totaltime = 0;
+		}
+	} while (best);
+
+	Con_Printf("Total time since last profile reset: %9.4f\n", Sys_DoubleTime() - prog->starttime);
+	Con_Printf("       - used by QC code of this VM: %9.4f\n", sum);
+
+	prog->starttime = Sys_DoubleTime();
+}
+
 void PRVM_Profile (int maxfunctions, int mininstructions)
 {
 	mfunction_t *f, *best;
@@ -307,6 +344,29 @@
 
 /*
 ============
+PRVM_CallProfile_f
+
+============
+*/
+void PRVM_CallProfile_f (void)
+{
+	if (Cmd_Argc() != 2)
+	{
+		Con_Print("prvm_callprofile <program name>\n");
+		return;
+	}
+
+	PRVM_Begin;
+	if(!PRVM_SetProgFromString(Cmd_Argv(1)))
+		return;
+
+	PRVM_CallProfile();
+
+	PRVM_End;
+}
+
+/*
+============
 PRVM_Profile_f
 
 ============
@@ -497,7 +557,10 @@
 	prvm_eval_t	*ptr;
 	int		jumpcount, cachedpr_trace, exitdepth;
 	int		restorevm_tempstringsbuf_cursize;
+	double  calltime;
 
+	calltime = Sys_DoubleTime();
+
 	if (!fnum || fnum >= (unsigned int)prog->progs->numfunctions)
 	{
 		if (prog->globaloffsets.self >= 0 && PRVM_GLOBALFIELDVALUE(prog->globaloffsets.self)->edict)
@@ -599,5 +662,7 @@
 	// delete tempstrings created by this function
 	vm_tempstringsbuf.cursize = restorevm_tempstringsbuf_cursize;
 
+	prog->functions[fnum].totaltime += (Sys_DoubleTime() - calltime);
+
 	SV_FlushBroadcastMessages();
 }

