Changeset: ee3770e3723d for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=ee3770e3723d
Modified Files:
monetdb5/mal/mal_function.c
monetdb5/mal/mal_instruction.c
monetdb5/mal/mal_instruction.h
monetdb5/mal/mal_interpreter.c
monetdb5/mal/mal_profiler.c
Branch: default
Log Message:
Generate dot files at start
When a dot file is required (for stethoscope) we run through
the program recursively to identify all MAL blocks and generate
its dot file once.
For the stethoscope, it means that all graphs are known before
the actual execution starts.
diffs (212 lines):
diff --git a/monetdb5/mal/mal_function.c b/monetdb5/mal/mal_function.c
--- a/monetdb5/mal/mal_function.c
+++ b/monetdb5/mal/mal_function.c
@@ -1069,14 +1069,44 @@ showFlowDetails(MalBlkPtr mb, MalStkPtr
mnstr_printf(f, "\"];\n");
}
+/* the stethoscope needs dot files for its graphical interface.
+ * They are produced whenever a main() is called.
+ * In all cases a single dot file is produced.
+ */
+#define MAXFLOWGRAPHS 128
+
+int getFlowGraphs(MalBlkPtr mb, MalStkPtr stk, MalBlkPtr *mblist, MalStkPtr
*stklist,int top);
+int getFlowGraphs(MalBlkPtr mb, MalStkPtr stk, MalBlkPtr *mblist, MalStkPtr
*stklist,int top){
+ int i;
+ InstrPtr p;
+
+ for ( i=0; i<top; i++)
+ if ( mblist[i] == mb)
+ return top;
+
+ if ( top == MAXFLOWGRAPHS)
+ return top; /* just bail out */
+ mblist[top] = mb;
+ stklist[top++] = stk;
+ for (i=1; i < mb->stop; i++){
+ p = getInstrPtr(mb,i);
+ if ( p->token == FCNcall || p->token == FACcall )
+ top =getFlowGraphs(p->blk, 0,mblist, stklist, top);
+ }
+ return top;
+}
+
void
showFlowGraph(MalBlkPtr mb, MalStkPtr stk, str fname)
{
stream *f;
InstrPtr p;
- int i, k;
+ int i, j,k, stethoscope=0;
char mapimode = 0;
buffer *bufstr = NULL;
+ MalBlkPtr mblist[MAXFLOWGRAPHS];
+ MalStkPtr stklist[MAXFLOWGRAPHS];
+ int top =0;
(void) stk; /* fool the compiler */
@@ -1088,40 +1118,52 @@ showFlowGraph(MalBlkPtr mb, MalStkPtr st
mapimode = 1;
} else if (idcmp(fname, "stethoscope") == 0) {
f = getProfilerStream();
+ stethoscope =1;
} else {
f = open_wastream(fname);
}
if ( f == NULL)
return;
- p = getInstrPtr(mb, 0);
- mnstr_printf(f, "digraph %s {\n", getFunctionId(p));
- p = getInstrPtr(mb, 0);
- showFlowDetails(mb, stk, p, 0, f);
- for (k = p->retc; k < p->argc; k++) {
- showOutFlow(mb, 0, p->argv[k], f);
+
+ top = getFlowGraphs(mb,stk,mblist,stklist,0);
+ if ( stethoscope == 0)
+ top =1;
+ for( j=0; j< top; j++){
+ mb = mblist[j];
+ stk = stklist[j];
+ if ( (mb == 0 || mb->dotfile) && stethoscope)
+ continue; /* already sent */
+ p = getInstrPtr(mb, 0);
+ mnstr_printf(f, "digraph %s {\n", getFunctionId(p));
+ p = getInstrPtr(mb, 0);
+ showFlowDetails(mb, stk, p, 0, f);
+ for (k = p->retc; k < p->argc; k++) {
+ showOutFlow(mb, 0, p->argv[k], f);
+ }
+ for (i = 1; i < mb->stop; i++) {
+ p = getInstrPtr(mb, i);
+
+ showFlowDetails(mb, stk, p, i, f);
+
+ for (k = 0; k < p->retc; k++)
+ showOutFlow(mb, i, p->argv[k], f);
+
+ if (p->retc == 0 || getArgType(mb, p, 0) == TYPE_void)
/* assume side effects */
+ for (k = p->retc; k < p->argc; k++)
+ if (getArgType(mb, p, k) != TYPE_void &&
+ !isVarConstant(mb, getArg(p,
k)))
+ showOutFlow(mb, i, p->argv[k],
f);
+
+ if (getFunctionId(p) == 0)
+ for (k = 0; k < p->retc; k++)
+ if (getArgType(mb, p, k) != TYPE_void)
+ showInFlow(mb, i, p->argv[k],
f);
+ if (p->token == ENDsymbol)
+ break;
+ }
+ mnstr_printf(f, "}\n");
+ mb->dotfile++;
}
- for (i = 1; i < mb->stop; i++) {
- p = getInstrPtr(mb, i);
-
- showFlowDetails(mb, stk, p, i, f);
-
- for (k = 0; k < p->retc; k++)
- showOutFlow(mb, i, p->argv[k], f);
-
- if (p->retc == 0 || getArgType(mb, p, 0) == TYPE_void) /*
assume side effects */
- for (k = p->retc; k < p->argc; k++)
- if (getArgType(mb, p, k) != TYPE_void &&
- !isVarConstant(mb, getArg(p, k)))
- showOutFlow(mb, i, p->argv[k], f);
-
- if (getFunctionId(p) == 0)
- for (k = 0; k < p->retc; k++)
- if (getArgType(mb, p, k) != TYPE_void)
- showInFlow(mb, i, p->argv[k], f);
- if (p->token == ENDsymbol)
- break;
- }
- mnstr_printf(f, "}\n");
if (mapimode == 1) {
size_t maxlen = 0;
diff --git a/monetdb5/mal/mal_instruction.c b/monetdb5/mal/mal_instruction.c
--- a/monetdb5/mal/mal_instruction.c
+++ b/monetdb5/mal/mal_instruction.c
@@ -118,6 +118,7 @@ newMalBlk(int maxvars, int maxstmts)
mb->alternative = NULL;
mb->history = NULL;
mb->keephistory = 0;
+ mb->dotfile = 0;
mb->marker = 0;
mb->maxarg = MAXARG; /* the minimum for each instruction */
mb->typefixed = 0;
@@ -200,6 +201,7 @@ copyMalBlk(MalBlkPtr old)
mb->alternative = old->alternative;
mb->history = NULL;
mb->keephistory = old->keephistory;
+ mb->dotfile = old->dotfile;
mb->marker = 0;
mb->var = (VarPtr *) GDKzalloc(sizeof(VarPtr) * old->vsize);
diff --git a/monetdb5/mal/mal_instruction.h b/monetdb5/mal/mal_instruction.h
--- a/monetdb5/mal/mal_instruction.h
+++ b/monetdb5/mal/mal_instruction.h
@@ -134,7 +134,8 @@ typedef struct MALBLK {
int flowfixed; /* all flow instructions are
fixed */
ProfPtr profiler;
struct MALBLK *history; /* of optimizer actions */
- int keephistory; /* do we need the history at
all */
+ short keephistory; /* do we need the history at
all */
+ short dotfile; /* sent dot file to
stethoscope? */
str marker; /* history points are
marked for backtracking */
int maxarg; /* keep track on the
maximal arguments used */
ptr replica; /* for the replicator tests */
diff --git a/monetdb5/mal/mal_interpreter.c b/monetdb5/mal/mal_interpreter.c
--- a/monetdb5/mal/mal_interpreter.c
+++ b/monetdb5/mal/mal_interpreter.c
@@ -538,7 +538,9 @@ callMAL(Client cntxt, MalBlkPtr mb, MalS
BBPincref(lhs->val.bval, TRUE);
}
stk->cmd = debug;
+ runtimeProfileBegin(cntxt, mb, stk, 0, &runtimeProfile, 1);
ret = runMALsequence(cntxt, mb, 1, 0, stk, 0, 0);
+ runtimeProfileExit(cntxt, mb, stk, &runtimeProfile);
break;
case FACTORYsymbol:
case FACcall:
@@ -994,8 +996,6 @@ str runMALsequence(Client cntxt, MalBlkP
}
if (stkpc == mb->stop) {
runtimeProfileExit(cntxt, mb, stk,
&runtimeProfile);
- runtimeProfile.ppc = 0; /* also
finalize function call event */
- runtimeProfileExit(cntxt, mb, stk,
&runtimeProfile);
if (cntxt->qtimeout && time(NULL) -
stk->clock.tv_usec > cntxt->qtimeout){
ret= createException(MAL,
"mal.interpreter", RUNTIME_QRY_TIMEOUT);
stkpc = mb->stop;
@@ -1216,9 +1216,6 @@ str runMALsequence(Client cntxt, MalBlkP
stkpc= mb->stop;
}
}
- /* also produce event record for end of function call */
- if ( startpc == 1 )
- runtimeProfileExit(cntxt, mb, stk, &runtimeProfileFunction);
/* if we could not find the exception variable, cascade a new one */
if (exceptionVar >= 0) {
diff --git a/monetdb5/mal/mal_profiler.c b/monetdb5/mal/mal_profiler.c
--- a/monetdb5/mal/mal_profiler.c
+++ b/monetdb5/mal/mal_profiler.c
@@ -160,9 +160,11 @@ profilerEvent(int idx, MalBlkPtr mb, Mal
{
if (mb->profiler == NULL) return;
if (profileCounter[PROFdot].status == 1 && start && pc == 0){
- mal_set_lock(mal_profileLock, "profileLock");
- showFlowGraph(mb,stk,"stethoscope");
- mal_unset_lock(mal_profileLock, "profileLock");
+ if (mb->dotfile == 0){
+ mal_set_lock(mal_profileLock, "profileLock");
+ showFlowGraph(mb,stk,"stethoscope");
+ mal_unset_lock(mal_profileLock, "profileLock");
+ }
}
if (profileCounter[PROFstart].status == 0 && start)
return;
_______________________________________________
Checkin-list mailing list
[email protected]
http://mail.monetdb.org/mailman/listinfo/checkin-list