1/*
2 * This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5 *
6 * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
7 */
8
9/*
10 * Martin Kersten
11 * Performance profiler
12 * A key issue in developing fast programs using the Monet database
13 * back-end requires a keen eye on where performance is lost.
14 * Although performance tracking and measurements are highly
15 * application dependent, a simple to use tool makes life
16 * a lot easier.
17 *
18 * Activation of the performance monitor has a global effect,
19 * i.e. all concurrent actions on the kernel are traced,
20 * but the events are only sent to the client initiated
21 * the profiler thread.
22 *
23 * The profiler event can be handled in several ways.
24 * The default strategy is to ship the event record immediately over a stream
25 * to a performance monitor.
26 * An alternative strategy is preparation of off-line performance analysis.
27 *
28 * To reduce the interference of performance measurement with
29 * the experiments, the user can use an event cache, which is
30 * emptied explicitly upon need.
31 */
32/*
33 * Using the Monet Performance Profiler is constrained by the mal_profiler.
34 */
35#include "monetdb_config.h"
36#include "profiler.h"
37
38str
39CMDopenProfilerStream(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pc)
40{
41 (void) cntxt;
42 (void) mb;
43 (void) stk;
44 (void) pc;
45 return openProfilerStream(cntxt);
46}
47
48str
49CMDcloseProfilerStream(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pc)
50{
51 (void) mb;
52 (void) stk;
53 (void) pc;
54 return closeProfilerStream(cntxt);
55}
56
57// initialize SQL tracing
58str
59CMDstartProfiler(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pc)
60{
61 (void)mb;
62 (void) stk;
63 (void) pc;
64 (void) cntxt;
65 return startProfiler(cntxt);
66}
67
68str
69CMDstopProfiler(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
70{
71 (void) mb;
72 (void) stk;
73 (void) pci;
74
75 return stopProfiler(cntxt);
76}
77
78// called by the SQL front end optional a directory to keep the traces.
79str
80CMDstartTrace(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
81{
82 (void) mb;
83 (void) stk;
84 (void) pci;
85 return startTrace(cntxt);
86}
87
88str
89CMDstopTrace(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
90{
91 (void) mb;
92 (void) stk;
93 (void) pci;
94 return stopTrace(cntxt);
95}
96
97str
98CMDnoopProfiler(void *res)
99{
100 (void) res; /* fool compiler */
101 return MAL_SUCCEED;
102}
103
104str
105CMDcleanupTraces(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
106{
107 (void) mb;
108 (void) stk;
109 (void) pci;
110 cleanupTraces(cntxt);
111 return MAL_SUCCEED;
112}
113
114str
115CMDgetTrace(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
116{
117 str path = *getArgReference_str(stk,pci,1);
118 bat *res = getArgReference_bat(stk,pci,0);
119 BAT *bn;
120
121 (void) cntxt; /* fool compiler */
122 (void) mb;
123 bn = getTrace(cntxt, path);
124 if (bn) {
125 BBPkeepref(*res = bn->batCacheid);
126 return MAL_SUCCEED;
127 }
128 throw(MAL, "getTrace", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING "%s", path);
129}
130
131str
132CMDgetprofilerlimit(int *res)
133{
134 *res = getprofilerlimit();
135 return MAL_SUCCEED;
136}
137
138str
139CMDsetprofilerlimit(void *res, int *lim)
140{
141 (void) res;
142 setprofilerlimit(*lim);
143 return MAL_SUCCEED;
144}
145
146/*
147 * Tracing an active system.
148 */
149
150str
151CMDsetHeartbeat(void *res, int *ev)
152{
153 (void) res;
154 setHeartbeat(*ev);
155 return MAL_SUCCEED;
156}
157
158str
159CMDgetDiskReads(lng *ret)
160{
161 *ret= getDiskReads();
162 return MAL_SUCCEED;
163}
164str
165CMDgetDiskWrites(lng *ret)
166{
167 *ret= getDiskWrites();
168 return MAL_SUCCEED;
169}
170str
171CMDgetUserTime(lng *ret)
172{
173 *ret= getUserTime();
174 return MAL_SUCCEED;
175}
176str
177CMDgetSystemTime(lng *ret)
178{
179 *ret= getUserTime();
180 return MAL_SUCCEED;
181}
182
183str
184CMDcpustats(lng *user, lng *nice, lng *sys, lng *idle, lng *iowait)
185{
186 profilerGetCPUStat(user,nice,sys,idle,iowait);
187 return MAL_SUCCEED;
188}
189
190str
191CMDcpuloadPercentage(int *cycles, int *io, lng *user, lng *nice, lng *sys, lng *idle, lng *iowait)
192{
193 lng userN, niceN, sysN, idleN, iowaitN, N;
194 *cycles = 0;
195 *io = 0;
196 profilerGetCPUStat(&userN,&niceN,&sysN,&idleN,&iowaitN);
197 N = (userN - *user + niceN - *nice + sysN - *sys);
198 if ( N){
199 *cycles = (int) ( ((double) N) / (N + idleN - *idle + iowaitN - *iowait) *100);
200 *io = (int) ( ((double) iowaitN- *iowait) / (N + idleN - *idle + iowaitN - *iowait) *100);
201 }
202 return MAL_SUCCEED;
203}
204