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