3 ** Copyright Kepler Project 2005-2007 (http://www.keplerproject.org/luaprofiler)
4 ** $Id: function_meter.c,v 1.9 2008/05/19 18:36:23 mascarenhas Exp $
7 /*****************************************************************************
9 Module to compute the times for functions (local times and total times)
12 'lprofM_init' set up the function times meter service
13 'lprofM_enter_function' called when the function stack increases one level
14 'lprofM_leave_function' called when the function stack decreases one level
16 'lprofM_resume_function' called when the profiler is returning from a time
18 'lprofM_resume_total_time' idem
19 'lprofM_resume_local_time' called when a child function returns the execution
20 to it's caller (current function)
21 'lprofM_pause_function' called when the profiler need to do things that
22 may take too long (writing a log, for example)
23 'lprofM_pause_total_time' idem
24 'lprofM_pause_local_time' called when the current function has called
25 another one or when the function terminates
26 *****************************************************************************/
33 /* #include "stack.h" is done by function_meter.h */
34 #include "function_meter.h"
38 #define ASSERT(e, msg) if (!e) { \
40 "function_meter.c: assertion failed: %s\n", \
44 #define ASSERT(e, msg)
47 /* structures to receive stack elements, declared globals */
48 /* in the hope they will perform faster */
49 static lprofS_STACK_RECORD newf
; /* used in 'enter_function' */
50 static lprofS_STACK_RECORD leave_ret
; /* used in 'leave_function' */
54 /* sum the seconds based on the time marker */
55 static void compute_local_time(lprofS_STACK_RECORD
*e
) {
56 ASSERT(e
, "local time null");
57 e
->local_time
+= lprofC_get_seconds(e
->time_marker_function_local_time
);
61 /* sum the seconds based on the time marker */
62 static void compute_total_time(lprofS_STACK_RECORD
*e
) {
63 ASSERT(e
, "total time null");
64 e
->total_time
+= lprofC_get_seconds(e
->time_marker_function_total_time
);
68 /* compute the local time for the current function */
69 void lprofM_pause_local_time(lprofP_STATE
* S
) {
70 compute_local_time(S
->stack_top
);
74 /* pause the total timer for all the functions that are in the stack */
75 void lprofM_pause_total_time(lprofP_STATE
* S
) {
78 ASSERT(S
->stack_top
, "pause_total_time: stack_top null");
85 compute_total_time(aux
);
91 /* pause the local and total timers for all functions in the stack */
92 void lprofM_pause_function(lprofP_STATE
* S
) {
94 ASSERT(S
->stack_top
, "pause_function: stack_top null");
96 lprofM_pause_local_time(S
);
97 lprofM_pause_total_time(S
);
101 /* resume the local timer for the current function */
102 void lprofM_resume_local_time(lprofP_STATE
* S
) {
104 ASSERT(S
->stack_top
, "resume_local_time: stack_top null");
106 /* the function is in the top of the stack */
107 lprofC_start_timer(&(S
->stack_top
->time_marker_function_local_time
));
111 /* resume the total timer for all the functions in the stack */
112 void lprofM_resume_total_time(lprofP_STATE
* S
) {
115 ASSERT(S
->stack_top
, "resume_total_time: stack_top null");
117 /* auxiliary stack */
122 lprofC_start_timer(&(aux
->time_marker_function_total_time
));
128 /* resume the local and total timers for all functions in the stack */
129 void lprofM_resume_function(lprofP_STATE
* S
) {
131 ASSERT(S
->stack_top
, "resume_function: stack_top null");
133 lprofM_resume_local_time(S
);
134 lprofM_resume_total_time(S
);
138 /* the local time for the parent function is paused */
139 /* and the local and total time markers are started */
140 void lprofM_enter_function(lprofP_STATE
* S
, char *file_defined
, char *fcn_name
, long linedefined
, long currentline
) {
143 /* the flow has changed to another function: */
144 /* pause the parent's function timer timer */
146 lprofM_pause_local_time(S
);
147 prev_name
= S
->stack_top
->function_name
;
148 } else prev_name
= "top level";
149 /* measure new function */
150 lprofC_start_timer(&(newf
.time_marker_function_local_time
));
151 lprofC_start_timer(&(newf
.time_marker_function_total_time
));
152 newf
.file_defined
= file_defined
;
153 if(fcn_name
!= NULL
) {
154 newf
.function_name
= fcn_name
;
155 } else if(strcmp(file_defined
, "=[C]") == 0) {
156 cur_name
= (char*)malloc(sizeof(char)*(strlen("called from ")+strlen(prev_name
)+1));
157 sprintf(cur_name
, "called from %s", prev_name
);
158 newf
.function_name
= cur_name
;
160 cur_name
= (char*)malloc(sizeof(char)*(strlen(file_defined
)+12));
161 sprintf(cur_name
, "%s:%li", file_defined
, linedefined
);
162 newf
.function_name
= cur_name
;
164 newf
.line_defined
= linedefined
;
165 newf
.current_line
= currentline
;
166 newf
.local_time
= 0.0;
167 newf
.total_time
= 0.0;
168 lprofS_push(&(S
->stack_top
), newf
);
172 /* computes times and remove the top of the stack */
173 /* 'isto_resume' specifies if the parent function's timer */
174 /* should be restarted automatically. If it's false, */
175 /* 'resume_local_time()' must be called when the resume */
177 /* returns the funcinfo structure */
178 /* warning: use it before another call to this function, */
179 /* because the funcinfo will be overwritten */
180 lprofS_STACK_RECORD
*lprofM_leave_function(lprofP_STATE
* S
, int isto_resume
) {
182 ASSERT(S
->stack_top
, "leave_function: stack_top null");
184 leave_ret
= lprofS_pop(&(S
->stack_top
));
185 compute_local_time(&leave_ret
);
186 compute_total_time(&leave_ret
);
187 /* resume the timer for the parent function ? */
189 lprofM_resume_local_time(S
);
195 lprofP_STATE
* lprofM_init() {
197 S
= (lprofP_STATE
*)malloc(sizeof(lprofP_STATE
));