Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge profiler configuration branch.

  • Loading branch information...
commit da19bd076e68fdc0353cb75b91c35a14e995f739 1 parent 40b1bc4
@rbetts rbetts authored
View
10 build.py
@@ -51,12 +51,20 @@
if gcc_major == 4 and gcc_minor >= 3:
CTX.CPPFLAGS += " -Wno-ignored-qualifiers -fno-strict-aliasing"
+if CTX.PROFILE:
+ CTX.CPPFLAGS += " -fvisibility=default -DPROFILE_ENABLED"
+
# linker flags
CTX.LDFLAGS = """ -g3 -rdynamic -ldl"""
+
if CTX.COVERAGE:
CTX.LDFLAGS += " -ftest-coverage -fprofile-arcs"
+
# for the google perftools profiler and the recommended stack unwinder
-#CTX.LDFLAGS = """ -g3 -rdynamic -lprofiler -lunwind"""
+# which you must have separately built and installed. Take some guesses
+# at the library location (/usr/local/lib).
+if CTX.PROFILE:
+ CTX.LDFLAGS = """ -L/usr/local/lib -g3 -rdynamic -lprofiler -lunwind"""
# this is where the build will look for header files
# - the test source will also automatically look in the test root dir
View
28 build.xml
@@ -264,7 +264,8 @@ DISTRIBUTION
***************************************
-->
-<target name="voltbin" depends="compile, ee, jars">
+<macrodef name="voltbin-macro">
+ <sequential>
<mkdir dir="${build.dir}/voltbin" />
<copy todir="${build.dir}/voltbin" flatten="true">
<fileset dir="${build.dir}" defaultexcludes="yes">
@@ -281,10 +282,20 @@ DISTRIBUTION
<!-- populate the logging configuration files -->
<copy tofile="${build.dir}/voltbin/log4j.properties" file="${src.gpl.dir}/log4j.properties"/>
<copy tofile="${build.dir}/voltbin/log4j.xml" file="${src.gpl.dir}/log4j.xml"/>
- <!-- strip the voltbin shared library (~40x size reduction) -->
- <exec dir='${build.dir}/voltbin' executable='/bin/sh'>
- <arg line="-c '/usr/bin/strip -x libvoltdb*'"/>
- </exec>
+ </sequential>
+</macrodef>
+
+<target name="voltbin" depends="compile, ee, jars">
+ <voltbin-macro/>
+
+ <!-- strip the voltbin shared library (~40x size reduction) -->
+ <exec dir='${build.dir}/voltbin' executable='/bin/sh'>
+ <arg line="-c '/usr/bin/strip -x libvoltdb*'"/>
+ </exec>
+</target>
+
+<target name="voltbin_profile" depends="compile, ee_profile, jars">
+ <voltbin-macro/>
</target>
<!-- Copy an example and move the basebuild.xml into that example -->
@@ -817,6 +828,13 @@ NATIVE EE STUFF
</exec>
</target>
+<target name='ee_profile' depends="catalog, jnicompile"
+ description="Build C++ JNI lib dl-ing perf tools and copy it to production folder.">
+ <exec dir='.' executable='python' failonerror='true'>
+ <arg line="build.py ${build} profile" />
+ </exec>
+</target>
+
<target name='execplanfrag' depends="ee"
description="Create test program that loads catalog and tables and executes a plan fragment.">
<exec dir='.' executable='python' failonerror='true'>
View
3  buildtools.py
@@ -26,6 +26,7 @@ def __init__(self, args):
self.NM = "/usr/bin/nm"
self.NMFLAGS = "-n" # specialized by platform in build.py
self.COVERAGE = False
+ self.PROFILE = False
for arg in [x.strip().upper() for x in args]:
if arg in ["DEBUG", "RELEASE", "MEMCHECK", "MEMCHECK_NOFREELIST"]:
self.LEVEL = arg
@@ -33,6 +34,8 @@ def __init__(self, args):
self.TARGET = arg
if arg in ["COVERAGE"]:
self.COVERAGE = True
+ if arg in ["PROFILE"]:
+ self.PROFILE = True
def readFile(filename):
"read a file into a string"
View
26 src/ee/voltdbjni.cpp
@@ -78,12 +78,13 @@
#endif // __SIZEOF_POINTER__ == 4
#else
#ifndef __x86_64
-#error VoltDB server does not compile or run on 32-bit platforms. The Java clien
-t library does (ant jars)
+#error VoltDB server does not compile or run on 32-bit platforms. The Java client library does (ant jars)
#endif // __x86_64
#endif // LINUX
-//#include <google/profiler.h>
+#ifdef PROFILE_ENABLED
+#include <google/profiler.h>
+#endif
//#include <jni/jni.h>
// TODO: gcc picks up wrong jni_md.h and results in compile error (bad
@@ -871,20 +872,21 @@ SHAREDLIB_JNIEXPORT jint JNICALL Java_org_voltdb_jni_ExecutionEngine_nativeToggl
(JNIEnv *env, jobject obj, jlong engine_ptr, jint toggle)
{
VOLT_DEBUG("nativeToggleProfiler in C++ called");
+// set on build command line via build.py
+#ifdef PROFILE_ENABLED
VoltDBEngine *engine = castToEngine(engine_ptr);
updateJNILogProxy(engine); //JNIEnv pointer can change between calls, must be updated
if (engine) {
-// if (toggle) {
-// ProfilerStart("/tmp/gprof.prof");
-// ProfilerDisable();
-// }
-// else {
-// ProfilerStop();
-// ProfilerFlush();
-// }
+ if (toggle) {
+ ProfilerStart("/tmp/gprof.prof");
+ }
+ else {
+ ProfilerStop();
+ ProfilerFlush();
+ }
return org_voltdb_jni_ExecutionEngine_ERRORCODE_SUCCESS;
-
}
+#endif
return org_voltdb_jni_ExecutionEngine_ERRORCODE_ERROR;
}
View
2  src/frontend/org/voltdb/compiler/VoltCompiler.java
@@ -872,7 +872,7 @@ void addSystemProcsToCatalog(final Catalog catalog, final Database database) thr
{"org.voltdb.sysprocs.SnapshotScan", "false", "false"},
{"org.voltdb.sysprocs.SnapshotDelete", "false", "false"},
{"org.voltdb.sysprocs.Shutdown", "false", "false"},
-// {"org.voltdb.sysprocs.StartSampler", "false", "false"},
+ {"org.voltdb.sysprocs.ProfCtl", "false", "false"},
{"org.voltdb.sysprocs.Statistics", "true", "false"},
{"org.voltdb.sysprocs.SystemInformation", "true", "false"},
{"org.voltdb.sysprocs.UpdateApplicationCatalog", "false", "true"},
View
47 ...end/org/voltdb/sysprocs/StartSampler.java → ...frontend/org/voltdb/sysprocs/ProfCtl.java
@@ -33,7 +33,7 @@
* in the documentation.
*/
@ProcInfo(singlePartition = false)
-public class StartSampler extends VoltSystemProcedure {
+public class ProfCtl extends VoltSystemProcedure {
Database m_db = null;
static final int DEP_ID = 1 | DtxnConstants.MULTIPARTITION_DEPENDENCY;
@@ -50,21 +50,58 @@ public void init(int numberOfPartitions, SiteProcedureConnection site,
public DependencyPair executePlanFragment(HashMap<Integer, List<VoltTable>> dependencies, long fragmentId,
ParameterSet params, SystemProcedureExecutionContext context) {
- VoltDB.instance().startSampler();
+ VoltTable table = new VoltTable(new ColumnInfo("Result", VoltType.STRING));
- VoltTable table = new VoltTable(new ColumnInfo("dummy", VoltType.BIGINT));
+ if (params.toArray()[0] != null) {
+ String command = (String)params.toArray()[0];
+ if (command.equalsIgnoreCase("SAMPLER_START")) {
+ VoltDB.instance().startSampler();
+ table.addRow("SAMPLER_START");
+ return new DependencyPair(DEP_ID, table);
+ }
+ else if (command.equalsIgnoreCase("GPERF_ENABLE") || command.equalsIgnoreCase("GPERF_DISABLE")) {
+ // Choose the lowest site ID on this host to do the work.
+ int host_id = context.getExecutionSite().getCorrespondingHostId();
+ Integer lowest_site_id =
+ VoltDB.instance().getCatalogContext().siteTracker.
+ getLowestLiveExecSiteIdForHost(host_id);
+ if (context.getExecutionSite().getSiteId() != lowest_site_id)
+ {
+ table.addRow("GPERF_NOOP");
+ return new DependencyPair(DEP_ID, table);
+ }
+ if (command.equalsIgnoreCase("GPERF_ENABLE")) {
+ context.getExecutionEngine().toggleProfiler(1);
+ table.addRow("GPERF_ENABLE");
+ return new DependencyPair(DEP_ID, table);
+ }
+ else {
+ context.getExecutionEngine().toggleProfiler(0);
+ table.addRow("GPERF_DISABLE");
+ return new DependencyPair(DEP_ID, table);
+ }
+ }
+ else {
+ table.addRow("Invalid command: " + command);
+ return new DependencyPair(DEP_ID, table);
+ }
+ }
+ table.addRow("No command.");
return new DependencyPair(DEP_ID, table);
}
- public VoltTable[] run(SystemProcedureExecutionContext ctx) {
+ public VoltTable[] run(SystemProcedureExecutionContext ctx, String command) {
SynthesizedPlanFragment spf = new SynthesizedPlanFragment();
spf.fragmentId = SysProcFragmentId.PF_startSampler;
spf.outputDepId = DEP_ID;
spf.inputDepIds = new int[] {};
spf.multipartition = true;
- spf.parameters = new ParameterSet();
+
+ ParameterSet params = new ParameterSet();
+ params.setParameters(command);
+ spf.parameters = params;
// distribute and execute these fragments providing pfs and id of the
// aggregator's output dependency table.
View
2  tests/frontend/org/voltdb/benchmark/BenchmarkController.java
@@ -380,10 +380,12 @@ public void setupBenchmark() {
debugString =
" -agentlib:jdwp=transport=dt_socket,address=8001,server=y,suspend=n ";
}
+
// -agentlib:hprof=cpu=samples,
// depth=32,interval=10,lineno=y,monitor=y,thread=y,force=y,
// file=" + host + "_hprof_tpcc.txt"
String[] command = {
+ "PROFILESELECTED=1",
"java",
"-XX:-ReduceInitialCardMarks",
"-XX:+HeapDumpOnOutOfMemoryError",
View
62 tests/frontend/org/voltdb/regressionsuites/TestSystemProcedureSuite.java
@@ -33,8 +33,7 @@
import org.voltdb.VoltTableRow;
import org.voltdb.VoltType;
import org.voltdb.benchmark.tpcc.TPCCProjectBuilder;
-import org.voltdb.client.Client;
-import org.voltdb.client.ProcCallException;
+import org.voltdb.client.*;
public class TestSystemProcedureSuite extends RegressionSuite {
@@ -311,6 +310,65 @@ public void testLoadMultipartitionTable() throws IOException {
}
+ // verify that the start sampler command doesn't blow up
+ public void testProfCtlStartSampler() throws Exception {
+ Client client = getClient();
+ ClientResponse resp = client.callProcedure("@ProfCtl", "SAMPLER_START");
+ VoltTable vt = resp.getResults()[0];
+ boolean foundResponse = false;
+ while (vt.advanceRow()) {
+ if (!vt.getString("Result").equalsIgnoreCase("sampler_start")) {
+ fail();
+ }
+ foundResponse = true;
+ }
+ assertTrue(foundResponse);
+ }
+
+ // verify that the gperf enable command doesn't blow up
+ public void testProfCtlGperfEnable() throws Exception {
+ Client client = getClient();
+ ClientResponse resp = client.callProcedure("@ProfCtl", "GPERF_ENABLE");
+ VoltTable vt = resp.getResults()[0];
+ boolean foundResponse = false;
+ while (vt.advanceRow()) {
+ if (vt.getString("Result").equalsIgnoreCase("GPERF_ENABLE")) {
+ foundResponse = true;
+ }
+ else {
+ assertTrue(vt.getString("Result").equalsIgnoreCase("GPERF_NOOP"));
+ }
+ }
+ assertTrue(foundResponse);
+ }
+
+
+ // verify that the gperf disable command doesn't blow up
+ public void testProfCtlGperfDisable() throws Exception {
+ Client client = getClient();
+ ClientResponse resp = client.callProcedure("@ProfCtl", "GPERF_DISABLE");
+ VoltTable vt = resp.getResults()[0];
+ boolean foundResponse = false;
+ while (vt.advanceRow()) {
+ if (vt.getString("Result").equalsIgnoreCase("gperf_disable")) {
+ foundResponse = true;
+ }
+ else {
+ assertTrue(vt.getString("Result").equalsIgnoreCase("GPERF_NOOP"));
+ }
+ }
+ assertTrue(foundResponse);
+ }
+
+
+ // verify correct behavior on invalid command
+ public void testProfCtlInvalidCommand() throws Exception {
+ Client client = getClient();
+ ClientResponse resp = client.callProcedure("@ProfCtl", "MakeAPony");
+ VoltTable vt = resp.getResults()[0];
+ assertTrue(true);
+ }
+
//
// Build a list of the tests to be run. Use the regression suite
// helpers to allow multiple backends.
View
35 tests/scripts/profctl.py
@@ -0,0 +1,35 @@
+#!/usr/bin/env python
+# -*- coding: utf-8
+
+# This file is part of VoltDB.
+# Copyright (C) 2008-2010 VoltDB Inc.
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+
+import sys
+from voltdbclient import *
+
+client = FastSerializer("localhost", 21212)
+proc = VoltProcedure(client, "@ProfCtl", [FastSerializer.VOLTTYPE_STRING])
+
+response = proc.call([sys.argv[1]])
+for x in response.tables:
+ print x
+
Please sign in to comment.
Something went wrong with that request. Please try again.