Skip to content

Commit

Permalink
Use DTrace for debugging instrumentation instead of hand-rolled stuff.
Browse files Browse the repository at this point in the history
The saio_debug module is now unused (and not even compiled in). The
rest of the code got cleaned up from adhoc debugging and instead now
exposes a few strategically positioned DTrace entry points.
  • Loading branch information
wulczer committed Oct 2, 2011
1 parent f9d2477 commit 3c1105d
Show file tree
Hide file tree
Showing 9 changed files with 117 additions and 127 deletions.
40 changes: 34 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,42 @@ REGRESS = $(patsubst test/sql/%.sql,%,$(TESTS))
REGRESS_OPTS = --inputdir=test
PG_CONFIG = pg_config

EXTRA_CLEAN = src/saio_probes.h

MODULE_big = saio
OBJS = \
src/saio_main.o src/saio_util.o src/saio_trees.o \
src/saio_move.o src/saio_pivot.o src/saio_recalc.o src/saio.o src/saio_debug.o
OBJS = src/saio_main.o src/saio_util.o src/saio_trees.o \
src/saio_recalc.o src/saio.o

# make sure
all: all-lib

# check for DTrace support
ifeq (,$(findstring --enable-dtrace,$(shell $(PG_CONFIG) --configure)))
enable_dtrace = no
else
enable_dtrace = yes
endif

ifeq ($(enable_dtrace), yes)
OBJS += src/saio_probes.o
endif

src/saio.o: src/saio_probes.h

src/saio_probes.o: src/saio_probes.d
$(DTRACE) -C -G -s $< -o $@

ifeq ($(enable_dtrace), no)
src/saio_probes.h: src/Gen_dummy_probes.sed
endif

# if the server is compiled with assertions, add the debug flag
ifneq (,$(findstring --enable-cassert,$(shell $(PG_CONFIG) --configure)))
PG_CPPFLAGS += -DSAIO_DEBUG
src/saio_probes.h: src/saio_probes.d
ifeq ($(enable_dtrace), yes)
$(DTRACE) -C -h -s $< -o $@.tmp
sed -e 's/SAIO_/TRACE_SAIO_/g' $@.tmp >$@
rm $@.tmp
else
sed -f src/Gen_dummy_probes.sed $< >$@
endif

PGXS := $(shell $(PG_CONFIG) --pgxs)
Expand Down
23 changes: 23 additions & 0 deletions src/Gen_dummy_probes.sed
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#-------------------------------------------------------------------------
# sed script to create dummy probes.h file when dtrace is not available
#
# Copyright (c) 2008-2011, PostgreSQL Global Development Group
#
# src/backend/utils/Gen_dummy_probes.sed
#-------------------------------------------------------------------------

/^[ ]*probe /!d
s/^[ ]*probe \([^(]*\)\(.*\);/\1\2/
s/__/_/g
y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/
s/^/#define TRACE_SAIO_/
s/([^,)]\{1,\})/(INT1)/
s/([^,)]\{1,\}, [^,)]\{1,\})/(INT1, INT2)/
s/([^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\})/(INT1, INT2, INT3)/
s/([^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\})/(INT1, INT2, INT3, INT4)/
s/([^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\})/(INT1, INT2, INT3, INT4, INT5)/
s/([^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\})/(INT1, INT2, INT3, INT4, INT5, INT6)/
s/([^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\})/(INT1, INT2, INT3, INT4, INT5, INT6, INT7)/
s/([^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\})/(INT1, INT2, INT3, INT4, INT5, INT6, INT7, INT8)/
P
s/(.*$/_ENABLED() (0)/
55 changes: 9 additions & 46 deletions src/saio.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
#include "saio.h"
#include "saio_util.h"
#include "saio_trees.h"
#include "saio_debug.h"
#include "saio_probes.h"

extern SaioAlgorithm algorithm;

Expand Down Expand Up @@ -177,6 +177,7 @@ saio(PlannerInfo *root, int levels_needed, List *initial_rels)
SaioPrivateData private;
bool ok;

TRACE_SAIO_PLANNING_START();

/* Initialize private data */
root->join_search_private = (void *) &private;
Expand Down Expand Up @@ -234,11 +235,6 @@ saio(PlannerInfo *root, int levels_needed, List *initial_rels)
/* Initialize the minimal state */
private.min_tree = NULL;

/* init debugging */
private.steps = NIL;
private.joinrels_built = 0;
private.loop_no = 0;

/* initialize the algorithm */
if (algorithm.initialize != NULL)
algorithm.initialize(root, tree);
Expand All @@ -253,60 +249,28 @@ saio(PlannerInfo *root, int levels_needed, List *initial_rels)

do {
saio_result move_result = SAIO_MOVE_OK;
#ifdef SAIO_STATS
/* save values for debugging */
SaioStep *step = palloc(sizeof(SaioStep));
#endif
move_result = algorithm.step(root, tree, all_trees);

TRACE_SAIO_STEP_DONE(move_result,
(int) rint(SAIO_COST(tree->rel)),
(int) rint(private.temperature),
private.elapsed_loops, private.failed_moves);

if (move_result == SAIO_MOVE_OK)
{
#ifdef SAIO_STATS
step->move_result = SAIO_MOVE_OK;
#endif
private.loop_no++;
private.failed_moves = 0;
}
else
{
#ifdef SAIO_STATS
step->move_result = move_result;
#endif
private.loop_no++;
private.failed_moves++;
}
#ifdef SAIO_STATS
step->cost = private.previous_cost;
step->temperature = private.temperature;
step->joinrels_built = private.joinrels_built;
private.steps = lappend(private.steps, step);
#endif
private.joinrels_built = 0;
elog(DEBUG1, "[%04d] at the end of the loop min tree is %p with cost %10.4f\n",
private.loop_no, private.min_tree,
private.min_tree == NULL ? 0 : private.min_cost);

} while (!equilibrium(root));

reduce_temperature(root);

} while (!frozen(root));

#ifdef SAIO_STATS
/* dump debugging values, free memory */
dump_debugging(&private);
list_free_deep(private.steps);
#endif

elog(DEBUG1, "[%04d] at the end of the algorithm min tree is %p with cost %10.4f\n",
private.loop_no, private.min_tree,
private.min_tree == NULL ? 0 : private.min_cost);

/* if there is a global minimum, pick it */
if (private.min_tree != NULL)
{
tree = private.min_tree;
elog(DEBUG1, "The cheapest tree is %10.4f\n", private.min_cost);
}

/* Finalize the algorithm */
Expand All @@ -316,16 +280,15 @@ saio(PlannerInfo *root, int levels_needed, List *initial_rels)
/* Rebuild the final rel in the correct memory context */
ok = recalculate_tree(root, tree);
Assert(ok);
snprintf(path, 256, "/tmp/saio-final.dot");
dump_query_tree(root, tree, NULL, NULL, true, path);
res = tree->rel;

/* Clean up */
list_free(all_trees);
MemoryContextDelete(private.sketch_context);
MemoryContextDelete(private.min_context);
root->join_search_private = NULL;
fflush(stdout);

TRACE_SAIO_PLANNING_DONE();

return res;
}
6 changes: 0 additions & 6 deletions src/saio.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
#ifndef SAIO_H
#define SAIO_H

char path[256];
#define SAIO_COST(rel) (rel)->cheapest_total_path->total_cost

#if PG_VERSION_NUM >= 90100
Expand Down Expand Up @@ -75,11 +74,6 @@ typedef struct SaioPrivateData {
double temperature; /* current system temperature */

unsigned short random_state[3]; /* state for erand48() */

/* debugging aids */
List *steps;
int joinrels_built;
int loop_no;
} SaioPrivateData;


Expand Down
6 changes: 0 additions & 6 deletions src/saio_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
#include "optimizer/geqo.h"

#include "saio.h"
#include "saio_debug.h"

PG_MODULE_MAGIC;

Expand Down Expand Up @@ -87,11 +86,6 @@ _PG_init(void)
/* Install hook */
prev_join_search_hook = join_search_hook;
join_search_hook = saio_main;

#ifdef SAIO_DEBUG
register_printf_specifier('T', print_tree_node, print_tree_node_arginfo);
register_printf_specifier('R', print_relids, print_relids_arginfo);
#endif
}

/* Module unload */
Expand Down
7 changes: 7 additions & 0 deletions src/saio_probes.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
provider saio {
probe planning_start();
probe planning_done();

/* param: status, current cost as integer, current temperature, elapsed loops, failed moves */
probe step_done(int, int, int, int, int);
}
43 changes: 43 additions & 0 deletions src/saio_probes.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/* Generated by the Systemtap dtrace wrapper */

#define _SDT_HAS_SEMAPHORES 1


#define STAP_HAS_SEMAPHORES 1 /* deprecated */


#include <sys/sdt.h>

/* TRACE_SAIO_PLANNING_START () */
#if defined STAP_SDT_V1
#define TRACE_SAIO_PLANNING_START_ENABLED() __builtin_expect (planning_start_semaphore, 0)
#define saio_planning_start_semaphore planning_start_semaphore
#else
#define TRACE_SAIO_PLANNING_START_ENABLED() __builtin_expect (saio_planning_start_semaphore, 0)
#endif
__extension__ extern unsigned short saio_planning_start_semaphore __attribute__ ((unused)) __attribute__ ((section (".probes")));
#define TRACE_SAIO_PLANNING_START() \
DTRACE_PROBE(saio,planning_start)

/* TRACE_SAIO_PLANNING_DONE () */
#if defined STAP_SDT_V1
#define TRACE_SAIO_PLANNING_DONE_ENABLED() __builtin_expect (planning_done_semaphore, 0)
#define saio_planning_done_semaphore planning_done_semaphore
#else
#define TRACE_SAIO_PLANNING_DONE_ENABLED() __builtin_expect (saio_planning_done_semaphore, 0)
#endif
__extension__ extern unsigned short saio_planning_done_semaphore __attribute__ ((unused)) __attribute__ ((section (".probes")));
#define TRACE_SAIO_PLANNING_DONE() \
DTRACE_PROBE(saio,planning_done)

/* TRACE_SAIO_STEP_DONE ( int, int, int, int, int) */
#if defined STAP_SDT_V1
#define TRACE_SAIO_STEP_DONE_ENABLED() __builtin_expect (step_done_semaphore, 0)
#define saio_step_done_semaphore step_done_semaphore
#else
#define TRACE_SAIO_STEP_DONE_ENABLED() __builtin_expect (saio_step_done_semaphore, 0)
#endif
__extension__ extern unsigned short saio_step_done_semaphore __attribute__ ((unused)) __attribute__ ((section (".probes")));
#define TRACE_SAIO_STEP_DONE(arg1,arg2,arg3,arg4,arg5) \
DTRACE_PROBE5(saio,step_done,arg1,arg2,arg3,arg4,arg5)

Loading

0 comments on commit 3c1105d

Please sign in to comment.