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

Reply via email to