Changeset: 2fdec5a6945c for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=2fdec5a6945c
Added Files:
        monetdb5/mal/mal_profiler.c
        monetdb5/mal/mal_profiler.h
Removed Files:
        monetdb5/mal/mal_profiler.mx
Modified Files:
        monetdb5/mal/Makefile.ag
Branch: default
Log Message:

de-Mx mal_profiler.mx


diffs (truncated from 2815 to 300 lines):

diff --git a/monetdb5/mal/Makefile.ag b/monetdb5/mal/Makefile.ag
--- a/monetdb5/mal/Makefile.ag
+++ b/monetdb5/mal/Makefile.ag
@@ -45,7 +45,7 @@ lib_mal = {
                mal_module.c mal_module.h \
                mal_namespace.c mal_namespace.h \
                mal_parser.mx \
-               mal_profiler.mx \
+               mal_profiler.c mal_profiler.h \
                mal_properties.c mal_properties.h \
                mal_readline.c mal_readline.h \
                mal_recycle.c mal_recycle.h \
diff --git a/monetdb5/mal/mal_profiler.c b/monetdb5/mal/mal_profiler.c
new file mode 100644
--- /dev/null
+++ b/monetdb5/mal/mal_profiler.c
@@ -0,0 +1,1205 @@
+/*
+ * The contents of this file are subject to the MonetDB Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.monetdb.org/Legal/MonetDBLicense
+ * 
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * The Original Code is the MonetDB Database System.
+ * 
+ * The Initial Developer of the Original Code is CWI.
+ * Portions created by CWI are Copyright (C) 1997-July 2008 CWI.
+ * Copyright August 2008-2012 MonetDB B.V.
+ * All Rights Reserved.
+*/
+
+/*
+ * Performance tracing
+ * The interpreter comes with several variables to hold performance
+ * related data.
+ * Every MAL instruction record is extended with two fields: counter and timer.
+ * The counter is incremented each time the instruction is taken into
+ * execution. Upon return, the timer is incremented with the microseconds
+ * spent.
+ * In addition to the default performance data collection,
+ * the user can request performance events to be collected on a statement
+ * basis. Care should be taken, because it leads to a large trace file,
+ * unless the results are directly passed to a performance monitor
+ * front-end for filtering and summarization.
+ *
+ * The performance monitor has exclusive access to the event file, which
+ * avoid concurrency conflicts amongst clients. It avoid cluthered
+ * event records on the event stream. Since this event stream is owned
+ * by a client, we should ensure that the profiler is automatically be
+ * reset once the owner leaves. The routine profilerReset() handles the case.
+ */
+#include "monetdb_config.h"
+#include "mal_function.h"
+#include "mal_listing.h"
+#include "mal_profiler.h"
+#include "mal_debugger.h"
+
+stream *eventstream = 0;
+
+static int offlineProfiling = FALSE;
+static int cachedProfiling = FALSE;
+static str myname = 0;
+
+int
+profilerAvailable(void)
+{
+       return 1;
+}
+static void offlineProfilerEvent(int idx, MalBlkPtr mb, MalStkPtr stk, int pc, 
int start);
+static void cachedProfilerEvent(int idx, MalBlkPtr mb, MalStkPtr stk, int pc);
+static int initTrace(void);
+
+int malProfileMode = 0;     /* global flag to indicate profiling mode */
+static int profileAll = 0;  /* all instructions should be profiled */
+static int delayswitch = 0; /* to wait before sending the profile info */
+
+#define PROFevent   0
+#define PROFtime    1
+#define PROFthread  2
+#define PROFpc      3
+#define PROFfunc    4
+#define PROFticks   5
+#define PROFcpu     6
+#define PROFmemory  7
+#define PROFreads   8
+#define PROFwrites  9
+#define PROFrbytes  10
+#define PROFwbytes  11
+#define PROFstmt    12
+#define PROFaggr    13
+#define PROFprocess 14
+#define PROFuser    15
+#define PROFstart   16
+#define PROFtype    17
+#define PROFdot     18
+#define PROFflow   19
+
+static struct {
+       str name;               /* which logical counter is needed */
+       int status;             /* trace it or not */
+} profileCounter[] = {
+       /*  0 */  { "event", 0},
+       /*  1 */  { "time", 0},
+       /*  2 */  { "thread", 0},
+       /*  3 */  { "pc", 0},
+       /*  4 */  { "function", 0},
+       /*  5 */  { "ticks", 0},
+       /*  6 */  { "cpu", 0},
+       /*  7 */  { "memory", 0},
+       /*  8 */  { "reads", 0},
+       /*  9 */  { "writes", 0},
+       /*  10 */  { "rbytes", 0},
+       /*  11 */  { "wbytes", 0},
+       /*  12 */  { "stmt", 0},
+       /*  13 */  { "aggregate", 0},
+       /*  14 */  { "process", 0},
+       /*  15 */  { "user", 0},
+       /*  16 */  { "start", 0},
+       /*  17 */  { "type", 0},
+       /*  18 */  { "dot", 0},
+       /*  19 */  { "flow", 0},
+       /*  20 */  { 0, 0}
+};
+
+/*
+ * The counters can be set individually.
+ */
+str
+activateCounter(str name)
+{
+       int i;
+       for (i = 0; profileCounter[i].name; i++)
+               if (strcmp(profileCounter[i].name, name) == 0) {
+                       profileCounter[i].status = 1;
+                       return 0;
+               }
+       throw(MAL, "activateCounter", RUNTIME_OBJECT_UNDEFINED ":%s", name);
+}
+
+str
+deactivateCounter(str name)
+{
+       int i;
+       for (i = 0; profileCounter[i].name; i++)
+               if (strcmp(profileCounter[i].name, name) == 0) {
+                       profileCounter[i].status = 0;
+                       return 0;
+               }
+       throw(MAL, "deactivateCounter", RUNTIME_OBJECT_UNDEFINED ":%s", name);
+}
+
+/*
+ * Offline processing
+ * The offline processing structure is the easiest. We merely have to
+ * produce a correct tuple format for the front-end.
+ */
+#define log(X, Y) if (eventstream) if (mnstr_printf(eventstream, X, Y) < 0) \
+               { closeProfilerStream(); }
+#define log0(X) if (eventstream) if (mnstr_printf(eventstream, X) < 0) \
+               { closeProfilerStream(); }
+#define log2(X, Y, Z) if (eventstream) if (mnstr_printf(eventstream, X, Y, Z) 
< 0) \
+               { closeProfilerStream(); }
+#define flushLog() if (eventstream) mnstr_flush(eventstream);
+
+/*
+ * Event dispatching
+ * The profiler strategy is encapsulated here
+ * Note that the profiler itself should lead to event generations.
+ */
+void
+profilerEvent(int idx, MalBlkPtr mb, MalStkPtr stk, int pc, int start)
+{
+       if (mb->profiler == NULL) return;
+       if (profileCounter[PROFdot].status == 1 && start && pc == 0)
+               showFlowGraph(mb,stk,"stethoscope");
+       if (profileCounter[PROFstart].status == 0 && start)
+               return;
+       if (myname == 0)
+               myname = putName("profiler", 8);
+       if (getModuleId(getInstrPtr(mb, pc)) == myname)
+               return;
+       if (offlineProfiling)
+               offlineProfilerEvent(idx, mb, stk, pc,start);
+       if (cachedProfiling)
+               cachedProfilerEvent(idx, mb, stk, pc);
+}
+
+static void
+offlineProfilerHeader(void)
+{
+       mal_set_lock(mal_profileLock, "profileLock");
+       if (eventstream == NULL) {
+               mal_unset_lock(mal_profileLock, "profileLock");
+               return ;
+       }
+       log0("# ");
+       if (profileCounter[PROFevent].status) {
+               log0("event,\tstatus,\t");
+       }
+       if (profileCounter[PROFtime].status) {
+               log0("time,\t");
+       }
+       if (profileCounter[PROFthread].status) {
+               log0("thread,\t");
+       }
+       if (profileCounter[PROFflow].status)
+               log0("claim,\tmemory,\t");
+       if (profileCounter[PROFfunc].status) {
+               log0("function,\t");
+       }
+       if (profileCounter[PROFpc].status) {
+               log0("pc,\t");
+       }
+       if (profileCounter[PROFticks].status) {
+               log0("usec,\t");
+       }
+       if (profileCounter[PROFcpu].status) {
+               log0("utime,\t");
+               log0("cutime,\t");
+               log0("stime,\t");
+               log0("cstime,\t");
+       }
+
+       if (profileCounter[PROFmemory].status) {
+               log0("maxrss,\t");
+               log0("arena,\t");
+               log0("ordblks,\t");
+               log0("smblks,\t");
+               log0("hblkhd,\t");
+               log0("hblks,\t");
+               log0("fsmblks,\t");
+               log0("uordblks,\t");
+       }
+       if (profileCounter[PROFreads].status)
+               log0("blk reads,\t");
+       if (profileCounter[PROFwrites].status)
+               log0("blk writes,\t");
+       if (profileCounter[PROFprocess].status) {
+               log0("pg reclaim,\t");
+               log0("pg faults,\t");
+               log0("swaps,\t");
+               log0("ctxt switch,\t");
+               log0("inv switch,\t");
+       }
+       if (profileCounter[PROFrbytes].status)
+               log0("rbytes,\t");
+       if (profileCounter[PROFwbytes].status)
+               log0("wbytes,\t");
+       if (profileCounter[PROFaggr].status)
+               log0("count,\t totalticks,\t");
+       if (profileCounter[PROFstmt].status)
+               log0("stmt,\t");
+       if (profileCounter[PROFtype].status)
+               log0("types,\t");
+       if (profileCounter[PROFuser].status)
+               log0("user,\t");
+       log0("# name\n");
+       flushLog();
+       mal_unset_lock(mal_profileLock, "profileLock");
+}
+
+void
+offlineProfilerEvent(int idx, MalBlkPtr mb, MalStkPtr stk, int pc, int start)
+{
+       static struct Mallinfo prevMalloc;
+       InstrPtr pci = getInstrPtr(mb, pc);
+
+#ifdef HAVE_SYS_RESOURCE_H
+       static struct rusage prevUsage;
+       struct rusage infoUsage;
+#endif
+       static int eventcounter;
+#ifdef HAVE_TIMES
+       struct tms newTms;
+#endif
+       struct Mallinfo infoMalloc;
+       str stmt, c;
+
+       if (delayswitch > 0) {
+               /* first call to profiled */
+               offlineProfilerHeader();
+               delayswitch--;
+       }
+       mal_set_lock(mal_profileLock, "profileLock");
+       if (eventstream == NULL) {
+               mal_unset_lock(mal_profileLock, "profileLock");
+               return ;
+       }
+       if (delayswitch == 0) {
+               delayswitch = -1;
+       }
+       if (!profileAll && mb->profiler[pc].trace == FALSE) {
+               mal_unset_lock(mal_profileLock, "profileLock");
+               return;
+       }
_______________________________________________
Checkin-list mailing list
[email protected]
http://mail.monetdb.org/mailman/listinfo/checkin-list

Reply via email to