]> sourceware.org Git - systemtap.git/commitdiff
2007-03-16 David Smith <dsmith@redhat.com>
authordsmith <dsmith>
Fri, 16 Mar 2007 15:29:34 +0000 (15:29 +0000)
committerdsmith <dsmith>
Fri, 16 Mar 2007 15:29:34 +0000 (15:29 +0000)
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
tapsets.cxx
translate.cxx

index 94666fefa82a56dbd5817b377ee2c4dbeade0ad1..07999692664c9a1eedbb877d3920377fe2027bd7 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,22 @@
+2007-03-16  David Smith  <dsmith@redhat.com>
+
+       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  <dsmith@redhat.com>
+
+
 2007-03-14  Martin Hunt  <hunt@redhat.com>     
        * main.cxx (usage): Remove "-M" and edit description
        of "-b".
index 2ca2457393827be6af41b441b175edc6753c1742..62c087c39cdeb4fa887586f6d864daa794bd6216 100644 (file)
@@ -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) << "}";
 }
 
index 2d826dcac7f4283ebbc0e480b4e5ae81a6bbe12b..3653037383c6d1d0398caf0a368e8210c9e0be98 100644 (file)
@@ -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";
This page took 0.044847 seconds and 5 git commands to generate.