From a58d79d097f6b801eb3a57cf928b515d8eccdf98 Mon Sep 17 00:00:00 2001 From: dsmith Date: Fri, 16 Mar 2007 15:29:34 +0000 Subject: [PATCH] 2007-03-16 David Smith PR 3545. * tapsets.cxx (common_probe_entryfn_prologue): Added 'overload_processing' parameter, which defaults to true. If overload_processing is set to false, doesn't output the STP_OVERLOAD code. (common_probe_entryfn_epilogue): Ditto. (be_derived_probe_group::emit_module_decl): Set overload_processing to false in calls to common_probe_entryfn_prologue and common_probe_entryfn_epilogue since begin/end probes shouldn't overload the system. * translate.cxx (c_unparser::emit_common_header): Emit STP_OVERLOAD global variables. (translate_pass): Emit STP_OVERLOAD defines. --- ChangeLog | 19 +++++++++++++ tapsets.cxx | 74 ++++++++++++++++++++++++++++++++++++++------------- translate.cxx | 20 +++++++++++++- 3 files changed, 94 insertions(+), 19 deletions(-) diff --git a/ChangeLog b/ChangeLog index 94666fefa..079996926 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2007-03-16 David Smith + + PR 3545. + * tapsets.cxx (common_probe_entryfn_prologue): Added + 'overload_processing' parameter, which defaults to true. If + overload_processing is set to false, doesn't output the + STP_OVERLOAD code. + (common_probe_entryfn_epilogue): Ditto. + (be_derived_probe_group::emit_module_decl): Set + overload_processing to false in calls to + common_probe_entryfn_prologue and common_probe_entryfn_epilogue + since begin/end probes shouldn't overload the system. + * translate.cxx (c_unparser::emit_common_header): Emit + STP_OVERLOAD global variables. + (translate_pass): Emit STP_OVERLOAD defines. + +2007-03-15 David Smith + + 2007-03-14 Martin Hunt * main.cxx (usage): Remove "-M" and edit description of "-b". diff --git a/tapsets.cxx b/tapsets.cxx index 2ca245739..62c087c39 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -128,16 +128,17 @@ be_derived_probe::join_group (systemtap_session& s) // ------------------------------------------------------------------------ void -common_probe_entryfn_prologue (translator_output* o, string statestr) +common_probe_entryfn_prologue (translator_output* o, string statestr, + bool overload_processing = true) { o->newline() << "struct context* __restrict__ c;"; o->newline() << "unsigned long flags;"; - o->newline() << "#ifdef STP_TIMING"; - // NB: we truncate cycles counts to 32 bits. Perhaps it should be - // fewer, if the hardware counter rolls over really quickly. See - // also ...epilogue(). - o->newline() << "int32_t cycles_atstart = (int32_t) get_cycles ();"; + if (overload_processing) + o->newline() << "#if defined(STP_TIMING) || defined(STP_OVERLOAD)"; + else + o->newline() << "#ifdef STP_TIMING"; + o->newline() << "cycles_t cycles_atstart = get_cycles ();"; o->newline() << "#endif"; #if 0 /* XXX: PERFMON */ @@ -192,18 +193,55 @@ common_probe_entryfn_prologue (translator_output* o, string statestr) void -common_probe_entryfn_epilogue (translator_output* o) +common_probe_entryfn_epilogue (translator_output* o, + bool overload_processing = true) { - o->newline() << "#ifdef STP_TIMING"; + if (overload_processing) + o->newline() << "#if defined(STP_TIMING) || defined(STP_OVERLOAD)"; + else + o->newline() << "#ifdef STP_TIMING"; o->newline() << "{"; - o->newline(1) << "int32_t cycles_atend = (int32_t) get_cycles ();"; - // Handle 32-bit wraparound. - o->newline() << "int32_t cycles_elapsed = (cycles_atend > cycles_atstart)"; - o->newline(1) << "? (cycles_atend - cycles_atstart)"; - o->newline() << ": (~(int32_t)0) - cycles_atstart + cycles_atend + 1;"; + o->newline(1) << "cycles_t cycles_atend = get_cycles ();"; + // NB: we truncate cycles counts to 32 bits. Perhaps it should be + // fewer, if the hardware counter rolls over really quickly. We + // handle 32-bit wraparound here. + o->newline() << "int32_t cycles_elapsed = ((int32_t)cycles_atend > (int32_t)cycles_atstart)"; + o->newline(1) << "? ((int32_t)cycles_atend - (int32_t)cycles_atstart)"; + o->newline() << ": (~(int32_t)0) - (int32_t)cycles_atstart + (int32_t)cycles_atend + 1;"; + o->indent(-1); + o->newline() << "#ifdef STP_TIMING"; o->newline() << "if (likely (c->statp)) _stp_stat_add(*c->statp, cycles_elapsed);"; - o->indent(-1); + o->newline() << "#endif"; + + if (overload_processing) + { + o->newline() << "#ifdef STP_OVERLOAD"; + o->newline() << "{"; + // If the cycle count has wrapped (cycles_atend > cycles_base), + // let's go ahead and pretend the interval has been reached. + // This should reset cycles_base and cycles_sum. + o->newline(1) << "cycles_t interval = (cycles_atend > c->cycles_base)"; + o->newline(1) << "? (cycles_atend - c->cycles_base)"; + o->newline() << ": (STP_OVERLOAD_INTERVAL + 1);"; + o->newline(-1) << "c->cycles_sum += cycles_elapsed;"; + + // If we've spent more than STP_OVERLOAD_THRESHOLD cycles in a + // probe during the last STP_OVERLOAD_INTERVAL cycles, the probe + // has overloaded the system and we need to quit. + o->newline() << "if (interval > STP_OVERLOAD_INTERVAL) {"; + o->newline(1) << "if (c->cycles_sum > STP_OVERLOAD_THRESHOLD) {"; + o->newline(1) << "_stp_error (\"probe overhead exceeded threshold\");"; + o->newline() << "atomic_set (&session_state, STAP_SESSION_ERROR);"; + o->newline(-1) << "}"; + + o->newline() << "c->cycles_base = cycles_atend;"; + o->newline() << "c->cycles_sum = 0;"; + o->newline(-1) << "}"; + o->newline(-1) << "}"; + o->newline() << "#endif"; + } + o->newline(-1) << "}"; o->newline() << "#endif"; @@ -238,17 +276,17 @@ be_derived_probe_group::emit_module_decls (systemtap_session& s) s.op->newline() << "/* ---- begin/end probes ---- */"; s.op->newline() << "void enter_begin_probe (void (*fn)(struct context*)) {"; s.op->indent(1); - common_probe_entryfn_prologue (s.op, "STAP_SESSION_STARTING"); + common_probe_entryfn_prologue (s.op, "STAP_SESSION_STARTING", false); s.op->newline() << "c->probe_point = \"begin\";"; s.op->newline() << "(*fn) (c);"; - common_probe_entryfn_epilogue (s.op); + common_probe_entryfn_epilogue (s.op, false); s.op->newline(-1) << "}"; s.op->newline() << "void enter_end_probe (void (*fn)(struct context*)) {"; s.op->indent(1); - common_probe_entryfn_prologue (s.op, "STAP_SESSION_STOPPING"); + common_probe_entryfn_prologue (s.op, "STAP_SESSION_STOPPING", false); s.op->newline() << "c->probe_point = \"end\";"; s.op->newline() << "(*fn) (c);"; - common_probe_entryfn_epilogue (s.op); + common_probe_entryfn_epilogue (s.op, false); s.op->newline(-1) << "}"; } diff --git a/translate.cxx b/translate.cxx index 2d826dcac..365303738 100644 --- a/translate.cxx +++ b/translate.cxx @@ -822,6 +822,10 @@ c_unparser::emit_common_header () o->newline() << "#ifdef STP_TIMING"; o->newline() << "Stat *statp;"; o->newline() << "#endif"; + o->newline() << "#ifdef STP_OVERLOAD"; + o->newline() << "cycles_t cycles_base;"; + o->newline() << "cycles_t cycles_sum;"; + o->newline() << "#endif"; o->newline() << "union {"; o->indent(1); @@ -4082,11 +4086,25 @@ translate_pass (systemtap_session& s) s.op->newline() << "#define MINSTACKSPACE 1024"; s.op->newline() << "#endif"; + // Overload processing + s.op->newline() << "#ifndef STP_OVERLOAD_INTERVAL"; + s.op->newline() << "#define STP_OVERLOAD_INTERVAL 1000000000LL"; + s.op->newline() << "#endif"; + s.op->newline() << "#ifndef STP_OVERLOAD_THRESHOLD"; + s.op->newline() << "#define STP_OVERLOAD_THRESHOLD 500000000LL"; + s.op->newline() << "#endif"; + // We allow the user to completely turn overload processing off + // (as opposed to tuning it by overriding the values above) by + // running: stap -DSTP_NO_OVERLOAD {other options} + s.op->newline() << "#ifndef STP_NO_OVERLOAD"; + s.op->newline() << "#define STP_OVERLOAD"; + s.op->newline() << "#endif"; + if (s.bulk_mode) s.op->newline() << "#define STP_BULKMODE"; if (s.timing) - s.op->newline() << "#define STP_TIMING" << " " << s.timing ; + s.op->newline() << "#define STP_TIMING"; if (s.perfmon) s.op->newline() << "#define STP_PERFMON"; -- 2.43.5