1 /*-------------------------------------------------------------------------
4 * functions for instrumentation of plan execution
7 * Copyright (c) 2001-2006, PostgreSQL Global Development Group
10 * $PostgreSQL: pgsql/src/backend/executor/instrument.c,v 1.18 2006/06/09 19:30:56 tgl Exp $
12 *-------------------------------------------------------------------------
18 #include "executor/instrument.h"
21 /* Allocate new instrumentation structure(s) */
25 Instrumentation *instr = palloc0(n * sizeof(Instrumentation));
27 /* we don't need to do any initialization except zero 'em */
32 /* Entry to a plan node */
34 InstrStartNode(Instrumentation *instr)
36 if (INSTR_TIME_IS_ZERO(instr->starttime))
37 INSTR_TIME_SET_CURRENT(instr->starttime);
39 elog(DEBUG2, "InstrStartNode called twice in a row");
42 /* Exit from a plan node */
44 InstrStopNode(Instrumentation *instr, double nTuples)
48 /* count the returned tuples */
49 instr->tuplecount += nTuples;
51 if (INSTR_TIME_IS_ZERO(instr->starttime))
53 elog(DEBUG2, "InstrStopNode called without start");
57 INSTR_TIME_SET_CURRENT(endtime);
60 instr->counter.tv_sec += endtime.tv_sec - instr->starttime.tv_sec;
61 instr->counter.tv_usec += endtime.tv_usec - instr->starttime.tv_usec;
63 /* Normalize after each add to avoid overflow/underflow of tv_usec */
64 while (instr->counter.tv_usec < 0)
66 instr->counter.tv_usec += 1000000;
67 instr->counter.tv_sec--;
69 while (instr->counter.tv_usec >= 1000000)
71 instr->counter.tv_usec -= 1000000;
72 instr->counter.tv_sec++;
75 instr->counter.QuadPart += (endtime.QuadPart - instr->starttime.QuadPart);
78 INSTR_TIME_SET_ZERO(instr->starttime);
80 /* Is this the first tuple of this cycle? */
83 instr->running = true;
84 instr->firsttuple = INSTR_TIME_GET_DOUBLE(instr->counter);
88 /* Finish a run cycle for a plan node */
90 InstrEndLoop(Instrumentation *instr)
94 /* Skip if nothing has happened, or already shut down */
98 if (!INSTR_TIME_IS_ZERO(instr->starttime))
99 elog(DEBUG2, "InstrEndLoop called on running node");
101 /* Accumulate per-cycle statistics into totals */
102 totaltime = INSTR_TIME_GET_DOUBLE(instr->counter);
104 instr->startup += instr->firsttuple;
105 instr->total += totaltime;
106 instr->ntuples += instr->tuplecount;
109 /* Reset for next cycle (if any) */
110 instr->running = false;
111 INSTR_TIME_SET_ZERO(instr->starttime);
112 INSTR_TIME_SET_ZERO(instr->counter);
113 instr->firsttuple = 0;
114 instr->tuplecount = 0;