This is the mail archive of the systemtap@sourceware.org mailing list for the systemtap project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [Bug translator/2421] translator emitting duplicate probe handlers


On Thu, 2006-08-10 at 16:18 -0400, Frank Ch. Eigler wrote:
> Hi -
> 
> With this code now in, it will be time for the next step of
> duplication elimination.  I hope this will make it clear why I talked
> dsmith out of the earlier amazing "48k" variant mentioned in
> http://sourceware.org/ml/systemtap/2006-q3/msg00208.html.
> 
> The next idea is to extend the translator guts to group all probes
> using the same lower level kernel API (kprobes / kretprobes / perfmon
> / any others) together.  Importantly, this grouping would *not* be
> based on any similarity amongst probe handler bodies, only the probe
> points!  The goal of this method is to give a new layer of translator
> code the chance to emit a single combined registration,
> unregistration, and callback function *for each group as a whole*.  (I
> have some C++ implementation ideas on this for the person who wants to
> undertake the work.)
> 
> Among other things, this sort of grouping is required for perfmon.
> When/if the kprobes API allows mass registration/unregistration, this
> will readily exploit it.  (It is a shame that the modules_get_byname()
> code was boo'd by essentially one ignorant critic, since by
> sorting/grouping all kprobes in the translator, we could most
> efficiently perform the necessary relocation / locking and still
> retain full generality.)
> 
> In any case, the result should be the elimination of even more
> duplication compared to the "48k" variant.  It should approximate the
> conceptual minimum amount of code required for the probe<->kernel
> glue.  Finally, if it is still economical to do so, some effort may be
> directed toward improving the code for ordinary
> statements/expressions.  Then we will be "done".

Here's a patch that provides the first level of probe grouping support.
This patch just contains structural changes to support probe grouping.
None of the actual probe emitting logic has changed - that's the next
step.

Here's a basic description of what's going on here.  There is a new base
class called 'derived_probe_group'.  It is designed to contain 1 type of
derived probe: be_derived_probe, dwarf_derived_probe, etc.  One derived
class of derived_probe_group is 'derived_probe_group_collection'.  This
is the object that contains all the other probe groups.

As each probe gets created, it calls register_probe(), which eventually
makes it back to the systemtap_session.probes member variable, which is
now an instance of a derived_probe_group_container.  The new probe gets
added to the appropriate derived_probe_group based on its type.

My next step will be to start modifying the probe emit logic to combine
1 registration/de-registration/callback function per group.

This patch is bigger than I would like, so any good ideas on how to
improve it would be appreciated.

-- 
David Smith
dsmith@redhat.com
Red Hat, Inc.
http://www.redhat.com
256.217.0141 (direct)
256.837.0057 (fax)

Index: buildrun.cxx
===================================================================
RCS file: /cvs/systemtap/src/buildrun.cxx,v
retrieving revision 1.24
diff -u -p -r1.24 buildrun.cxx
--- buildrun.cxx	30 Jun 2006 18:24:43 -0000	1.24
+++ buildrun.cxx	18 Aug 2006 19:18:45 -0000
@@ -8,6 +8,7 @@
 
 #include "config.h"
 #include "buildrun.h"
+#include "session.h"
 
 #include <fstream>
 #include <sstream>
Index: elaborate.cxx
===================================================================
RCS file: /cvs/systemtap/src/elaborate.cxx,v
retrieving revision 1.64
diff -u -p -r1.64 elaborate.cxx
--- elaborate.cxx	14 Aug 2006 21:09:21 -0000	1.64
+++ elaborate.cxx	18 Aug 2006 19:18:45 -0000
@@ -10,6 +10,7 @@
 #include "elaborate.h"
 #include "parse.h"
 #include "tapsets.h"
+#include "session.h"
 
 extern "C" {
 #include <sys/utsname.h>
@@ -70,6 +71,58 @@ derived_probe::derived_probe (probe *p, 
 
 
 // ------------------------------------------------------------------------
+// Members of derived_probe_group
+
+void
+derived_probe_group::register_probe(be_derived_probe* p)
+{
+  throw semantic_error ("unexpected registration of a be_derived_probe");
+}
+
+
+void
+derived_probe_group::register_probe(dwarf_derived_probe* p)
+{
+  throw semantic_error ("unexpected registration of a dwarf_derived_probe");
+}
+
+
+void
+derived_probe_group::register_probe(hrtimer_derived_probe* p)
+{
+  throw semantic_error ("unexpected registration of a hrtimer_derived_probe");
+}
+
+
+void
+derived_probe_group::register_probe(mark_derived_probe* p)
+{
+  throw semantic_error ("unexpected registration of a mark_derived_probe");
+}
+
+
+void
+derived_probe_group::register_probe(never_derived_probe* p)
+{
+  throw semantic_error ("unexpected registration of a never_derived_probe");
+}
+
+
+void
+derived_probe_group::register_probe(profile_derived_probe* p)
+{
+  throw semantic_error ("unexpected registration of a profile_derived_probe");
+}
+
+
+void
+derived_probe_group::register_probe(timer_derived_probe* p)
+{
+  throw semantic_error ("unexpected registration of a timer_derived_probe");
+}
+
+
+// ------------------------------------------------------------------------
 // Members of derived_probe_builder
 
 bool
@@ -330,6 +383,8 @@ struct alias_derived_probe: public deriv
 {
   alias_derived_probe (probe* base): derived_probe (base) {}
 
+  void register_probe (systemtap_session& s) { }
+
   // alias probes should be ultimately expanded to other derived_probe
   // types, and not themselves emitted.
   void emit_registrations (translator_output* o) { throw semantic_error ("inappropriate", this->tok); }
@@ -882,7 +937,7 @@ semantic_pass_symbols (systemtap_session
           for (unsigned j=0; j<dps.size(); j++)
             {
               derived_probe* dp = dps[j];
-	      s.probes.push_back (dp);
+	      dp->register_probe (s);
 
               try 
                 {
Index: elaborate.h
===================================================================
RCS file: /cvs/systemtap/src/elaborate.h,v
retrieving revision 1.31
diff -u -p -r1.31 elaborate.h
--- elaborate.h	2 Jun 2006 23:13:38 -0000	1.31
+++ elaborate.h	18 Aug 2006 19:18:45 -0000
@@ -9,7 +9,6 @@
 #ifndef ELABORATE_H
 #define ELABORATE_H
 
-#include "session.h"
 #include "staptree.h"
 #include "parse.h"
 #include <string>
@@ -116,6 +115,8 @@ struct derived_probe: public probe
 
   virtual ~derived_probe () {}
 
+  virtual void register_probe (systemtap_session& s) = 0;
+
   virtual void emit_registrations (translator_output* o) = 0;
   // (from within module_init):
   // rc = ..... register_or_whatever (ENTRYFN);
@@ -148,6 +149,33 @@ public:
 
 // ------------------------------------------------------------------------
 
+struct be_derived_probe;
+struct dwarf_derived_probe;
+struct hrtimer_derived_probe;
+struct mark_derived_probe;
+struct never_derived_probe;
+struct profile_derived_probe;
+struct timer_derived_probe;
+struct unparser;
+
+struct derived_probe_group
+{
+  virtual ~derived_probe_group () {}
+
+  virtual void register_probe(be_derived_probe* p);
+  virtual void register_probe(dwarf_derived_probe* p);
+  virtual void register_probe(hrtimer_derived_probe* p);
+  virtual void register_probe(mark_derived_probe* p);
+  virtual void register_probe(never_derived_probe* p);
+  virtual void register_probe(profile_derived_probe* p);
+  virtual void register_probe(timer_derived_probe* p);
+  virtual size_t size () = 0;
+
+  virtual void emit_probes (translator_output* op, unparser* up) = 0;
+};
+
+// ------------------------------------------------------------------------
+
 struct derived_probe_builder
 {
   virtual void build(systemtap_session & sess,
@@ -218,4 +246,37 @@ void derive_probes (systemtap_session& s
 symbol * get_symbol_within_expression (expression *e);
 
 
+struct unparser;
+
+struct derived_probe_group_container: public derived_probe_group
+{
+private:
+  std::vector<derived_probe*> probes;
+  derived_probe_group* be_probe_group;
+  derived_probe_group* dwarf_probe_group;
+  derived_probe_group* hrtimer_probe_group;
+  derived_probe_group* mark_probe_group;
+  derived_probe_group* never_probe_group;
+  derived_probe_group* profile_probe_group;
+  derived_probe_group* timer_probe_group;
+
+public:
+  derived_probe_group_container ();
+  ~derived_probe_group_container ();
+
+  void register_probe (be_derived_probe* p);
+  void register_probe (dwarf_derived_probe* p);
+  void register_probe (hrtimer_derived_probe* p);
+  void register_probe (mark_derived_probe* p);
+  void register_probe (never_derived_probe* p);
+  void register_probe (profile_derived_probe* p);
+  void register_probe (timer_derived_probe* p);
+  size_t size () { return (probes.size ()); }
+
+  derived_probe* operator[] (size_t n) { return (probes[n]); }
+
+  void emit_probes (translator_output* op, unparser* up);
+};
+
+
 #endif // ELABORATE_H
Index: main.cxx
===================================================================
RCS file: /cvs/systemtap/src/main.cxx,v
retrieving revision 1.49
diff -u -p -r1.49 main.cxx
--- main.cxx	17 Jul 2006 08:25:00 -0000	1.49
+++ main.cxx	18 Aug 2006 19:18:46 -0000
@@ -14,6 +14,7 @@
 #include "elaborate.h"
 #include "translate.h"
 #include "buildrun.h"
+#include "session.h"
 
 #include <iostream>
 #include <fstream>
Index: parse.h
===================================================================
RCS file: /cvs/systemtap/src/parse.h,v
retrieving revision 1.22
diff -u -p -r1.22 parse.h
--- parse.h	13 Jul 2006 20:41:00 -0000	1.22
+++ parse.h	18 Aug 2006 19:18:46 -0000
@@ -59,6 +59,8 @@ struct parse_error: public std::runtime_
 };
 
 
+struct systemtap_session;
+
 class lexer
 {
 public:
@@ -77,6 +79,29 @@ private:
 };
 
 
+struct stapfile;
+struct probe;
+struct probe_alias;
+struct vardecl;
+struct functiondecl;
+struct embeddedcode;
+struct probe_point;
+struct literal;
+struct block;
+struct for_loop;
+struct statement;
+struct if_statement;
+struct foreach_loop;
+struct expr_statement;
+struct return_statement;
+struct delete_statement;
+struct break_statement;
+struct next_statement;
+struct continue_statement;
+struct indexable;
+struct expression;
+struct hist_op;
+
 class parser
 {
 public:
Index: session.h
===================================================================
RCS file: /cvs/systemtap/src/session.h,v
retrieving revision 1.7
diff -u -p -r1.7 session.h
--- session.h	9 May 2006 09:33:19 -0000	1.7
+++ session.h	18 Aug 2006 19:18:46 -0000
@@ -9,6 +9,7 @@
 #ifndef SESSION_H
 #define SESSION_H
 
+#include "elaborate.h"
 #include <string>
 #include <vector>
 #include <iostream>
@@ -21,7 +22,7 @@ struct match_node;
 struct stapfile;
 struct vardecl;
 struct functiondecl;
-struct derived_probe;
+struct derived_probe_group_container;
 struct embeddedcode;
 struct translator_output;
 struct unparser;
@@ -94,7 +95,7 @@ struct systemtap_session
   std::vector<stapfile*> files;
   std::vector<vardecl*> globals;
   std::vector<functiondecl*> functions;
-  std::vector<derived_probe*> probes;
+  derived_probe_group_container probes;
   std::vector<embeddedcode*> embeds;
   std::map<std::string, statistic_decl> stat_decls;
   // XXX: vector<*> instead please?
Index: staptree.h
===================================================================
RCS file: /cvs/systemtap/src/staptree.h,v
retrieving revision 1.42
diff -u -p -r1.42 staptree.h
--- staptree.h	9 Jun 2006 09:20:03 -0000	1.42
+++ staptree.h	18 Aug 2006 19:18:46 -0000
@@ -9,7 +9,6 @@
 #ifndef STAPTREE_H
 #define STAPTREE_H
 
-#include "session.h"
 #include <map>
 #include <stack>
 #include <set>
Index: tapsets.cxx
===================================================================
RCS file: /cvs/systemtap/src/tapsets.cxx,v
retrieving revision 1.138
diff -u -p -r1.138 tapsets.cxx
--- tapsets.cxx	1 Aug 2006 02:20:47 -0000	1.138
+++ tapsets.cxx	18 Aug 2006 19:18:46 -0000
@@ -12,6 +12,7 @@
 #include "elaborate.h"
 #include "tapsets.h"
 #include "translate.h"
+#include "session.h"
 
 #include <deque>
 #include <iostream>
@@ -198,12 +199,27 @@ struct be_derived_probe: public derived_
   be_derived_probe (probe* p, probe_point* l, bool b):
     derived_probe (p, l), begin (b) {}
 
+  void register_probe (systemtap_session& s);
+
   void emit_registrations (translator_output* o);
   void emit_deregistrations (translator_output* o);
   void emit_probe_entries (translator_output* o);
 };
 
 
+struct be_derived_probe_group: public derived_probe_group
+{
+private:
+  vector<be_derived_probe*> probes;
+
+public:
+  virtual void register_probe(be_derived_probe* p) { probes.push_back (p); }
+  virtual size_t size () { return probes.size (); }
+
+  virtual void emit_probes (translator_output* op, unparser* up);
+};
+
+
 struct be_builder: public derived_probe_builder
 {
   bool begin;
@@ -220,6 +236,13 @@ struct be_builder: public derived_probe_
 
 
 void
+be_derived_probe::register_probe(systemtap_session& s)
+{
+  s.probes.register_probe(this);
+}
+
+
+void
 be_derived_probe::emit_registrations (translator_output* o)
 {
   if (begin)
@@ -270,6 +293,17 @@ be_derived_probe::emit_probe_entries (tr
 }
 
 
+void
+be_derived_probe_group::emit_probes (translator_output* op, unparser* up)
+{
+  for (unsigned i=0; i < probes.size(); i++)
+    {
+      op->newline ();
+      up->emit_probe (probes[i]);
+    }
+}
+
+
 // ------------------------------------------------------------------------
 // never probes are never run
 // ------------------------------------------------------------------------
@@ -279,12 +313,34 @@ struct never_derived_probe: public deriv
   never_derived_probe (probe* p): derived_probe (p) {}
   never_derived_probe (probe* p, probe_point* l): derived_probe (p, l) {}
 
+  void register_probe (systemtap_session& s);
+
   void emit_registrations (translator_output* o);
   void emit_deregistrations (translator_output* o);
   void emit_probe_entries (translator_output* o);
 };
 
 
+struct never_derived_probe_group: public derived_probe_group
+{
+private:
+  vector<never_derived_probe*> probes;
+
+public:
+  virtual void register_probe(never_derived_probe* p) { probes.push_back (p); }
+  virtual size_t size () { return probes.size (); }
+
+  virtual void emit_probes (translator_output* op, unparser* up);
+};
+
+
+void
+never_derived_probe::register_probe(systemtap_session& s)
+{
+  s.probes.register_probe(this);
+}
+
+
 struct never_builder: public derived_probe_builder
 {
   never_builder() {}
@@ -317,6 +373,15 @@ never_derived_probe::emit_probe_entries 
 }
 
 
+void
+never_derived_probe_group::emit_probes (translator_output* op, unparser* up)
+{
+  for (unsigned i=0; i < probes.size(); i++)
+    {
+      op->newline ();
+      up->emit_probe (probes[i]);
+    }
+}
 
 // ------------------------------------------------------------------------
 //  Dwarf derived probes.
@@ -1717,6 +1782,8 @@ struct dwarf_derived_probe : public deri
   vector<Dwarf_Addr> probe_points;
   bool has_return;
 
+  void register_probe (systemtap_session& s);
+
   void add_probe_point(string const & funcname,
 		       char const * filename,
 		       int line,
@@ -1741,6 +1808,20 @@ struct dwarf_derived_probe : public deri
   virtual void emit_probe_entries (translator_output * o);
 };
 
+
+struct dwarf_derived_probe_group: public derived_probe_group
+{
+private:
+  vector<dwarf_derived_probe*> probes;
+
+public:
+  virtual void register_probe(dwarf_derived_probe* p) { probes.push_back (p); }
+  virtual size_t size () { return probes.size (); }
+
+  virtual void emit_probes (translator_output* op, unparser* up);
+};
+
+
 // Helper struct to thread through the dwfl callbacks.
 struct
 dwarf_query
@@ -2938,6 +3019,13 @@ dwarf_var_expanding_copy_visitor::visit_
 
 
 void
+dwarf_derived_probe::register_probe(systemtap_session& s)
+{
+  s.probes.register_probe(this);
+}
+
+
+void
 dwarf_derived_probe::add_probe_point(string const & funcname,
 				     char const * filename,
 				     int line,
@@ -3374,6 +3462,17 @@ dwarf_derived_probe::emit_probe_entries 
 
 
 void
+dwarf_derived_probe_group::emit_probes (translator_output* op, unparser* up)
+{
+  for (unsigned i=0; i < probes.size(); i++)
+    {
+      op->newline ();
+      up->emit_probe (probes[i]);
+    }
+}
+
+
+void
 dwarf_builder::build(systemtap_session & sess,
 		     probe * base,
 		     probe_point * location,
@@ -3463,6 +3562,8 @@ struct timer_derived_probe: public deriv
 
   timer_derived_probe (probe* p, probe_point* l, int64_t i, int64_t r, bool ms=false);
 
+  virtual void register_probe (systemtap_session& s);
+
   virtual void emit_registrations (translator_output * o);
   virtual void emit_deregistrations (translator_output * o);
   virtual void emit_probe_entries (translator_output * o);
@@ -3485,6 +3586,13 @@ timer_derived_probe::timer_derived_probe
 
 
 void
+timer_derived_probe::register_probe(systemtap_session& s)
+{
+  s.probes.register_probe(this);
+}
+
+
+void
 timer_derived_probe::emit_registrations (translator_output* o)
 {
   o->newline() << "init_timer (& timer_" << name << ");";
@@ -3539,6 +3647,30 @@ timer_derived_probe::emit_probe_entries 
 }
 
 
+struct timer_derived_probe_group: public derived_probe_group
+{
+private:
+  vector<timer_derived_probe*> probes;
+
+public:
+  virtual void register_probe(timer_derived_probe* p) { probes.push_back (p); }
+  virtual size_t size () { return probes.size (); }
+
+  virtual void emit_probes (translator_output* op, unparser* up);
+};
+
+
+void
+timer_derived_probe_group::emit_probes (translator_output* op, unparser* up)
+{
+  for (unsigned i=0; i < probes.size(); i++)
+    {
+      op->newline ();
+      up->emit_probe (probes[i]);
+    }
+}
+
+
 struct timer_builder: public derived_probe_builder
 {
   bool time_is_msecs;
@@ -3580,6 +3712,8 @@ struct profile_derived_probe: public der
 
   profile_derived_probe (systemtap_session &s, probe* p, probe_point* l);
 
+  void register_probe (systemtap_session& s);
+
   virtual void emit_registrations (translator_output * o);
   virtual void emit_deregistrations (translator_output * o);
   virtual void emit_probe_entries (translator_output * o);
@@ -3603,6 +3737,13 @@ profile_derived_probe::profile_derived_p
 
 
 void
+profile_derived_probe::register_probe(systemtap_session& s)
+{
+  s.probes.register_probe(this);
+}
+
+
+void
 profile_derived_probe::emit_registrations (translator_output* o)
 {
   if (using_rpn)
@@ -3659,6 +3800,31 @@ profile_derived_probe::emit_probe_entrie
 }
 
 
+struct profile_derived_probe_group: public derived_probe_group
+{
+private:
+  vector<profile_derived_probe*> probes;
+
+public:
+  virtual void register_probe(profile_derived_probe* p) {
+    probes.push_back (p); }
+  virtual size_t size () { return probes.size (); }
+
+  virtual void emit_probes (translator_output* op, unparser* up);
+};
+
+
+void
+profile_derived_probe_group::emit_probes (translator_output* op, unparser* up)
+{
+  for (unsigned i=0; i < probes.size(); i++)
+    {
+      op->newline ();
+      up->emit_probe (probes[i]);
+    }
+}
+
+
 struct profile_builder: public derived_probe_builder
 {
   profile_builder() {}
@@ -3691,6 +3857,8 @@ struct mark_derived_probe: public derive
   string module;
   string probe_sig_expanded;
 
+  void register_probe (systemtap_session& s);
+
   void emit_registrations (translator_output * o);
   void emit_deregistrations (translator_output * o);
   void emit_probe_entries (translator_output * o);
@@ -3808,6 +3976,13 @@ mark_derived_probe::mark_derived_probe (
 
 
 void
+mark_derived_probe::register_probe(systemtap_session& s)
+{
+  s.probes.register_probe(this);
+}
+
+
+void
 mark_derived_probe::emit_probe_context_vars (translator_output* o)
 {
   // Save incoming arguments
@@ -3903,6 +4078,29 @@ mark_derived_probe::emit_deregistrations
 }
 
 
+struct mark_derived_probe_group: public derived_probe_group
+{
+private:
+  vector<mark_derived_probe*> probes;
+
+public:
+  virtual void register_probe(mark_derived_probe* p) { probes.push_back (p); }
+  virtual size_t size () { return probes.size (); }
+
+  virtual void emit_probes (translator_output* op, unparser* up);
+};
+
+
+void
+mark_derived_probe_group::emit_probes (translator_output* op, unparser* up)
+{
+  for (unsigned i=0; i < probes.size(); i++)
+    {
+      op->newline ();
+      up->emit_probe (probes[i]);
+    }
+}
+
 
 struct symboltable_extract
 {
@@ -4113,6 +4311,8 @@ struct hrtimer_derived_probe: public der
     // so we don't have to loop over them in the other functions
   }
 
+  void register_probe (systemtap_session& s);
+
   virtual void emit_interval (translator_output * o);
 
   virtual void emit_registrations (translator_output * o);
@@ -4122,6 +4322,13 @@ struct hrtimer_derived_probe: public der
 
 
 void
+hrtimer_derived_probe::register_probe(systemtap_session& s)
+{
+  s.probes.register_probe(this);
+}
+
+
+void
 hrtimer_derived_probe::emit_interval (translator_output* o)
 {
   o->line() << "({";
@@ -4193,6 +4400,30 @@ hrtimer_derived_probe::emit_probe_entrie
 }
 
 
+struct hrtimer_derived_probe_group: public derived_probe_group
+{
+private:
+  vector<hrtimer_derived_probe*> probes;
+
+public:
+  virtual void register_probe(hrtimer_derived_probe* p) { probes.push_back (p); }
+  virtual size_t size () { return probes.size (); }
+
+  virtual void emit_probes (translator_output* op, unparser* up);
+};
+
+
+void
+hrtimer_derived_probe_group::emit_probes (translator_output* op, unparser* up)
+{
+  for (unsigned i=0; i < probes.size(); i++)
+    {
+      op->newline ();
+      up->emit_probe (probes[i]);
+    }
+}
+
+
 struct hrtimer_builder: public derived_probe_builder
 {
   hrtimer_builder() {}
@@ -4347,3 +4578,114 @@ register_standard_tapsets(systemtap_sess
   s.pattern_root->bind("kernel")->bind_str("mark")->bind(new mark_builder());
   s.pattern_root->bind_str("module")->bind_str("mark")->bind(new mark_builder());
 }
+
+
+derived_probe_group_container::derived_probe_group_container ():
+  be_probe_group(new be_derived_probe_group),
+  dwarf_probe_group(new dwarf_derived_probe_group),
+  hrtimer_probe_group(new hrtimer_derived_probe_group),
+  mark_probe_group(new mark_derived_probe_group),
+  never_probe_group(new never_derived_probe_group),
+  profile_probe_group(new profile_derived_probe_group),
+  timer_probe_group(new timer_derived_probe_group)
+{
+}
+
+
+derived_probe_group_container::~derived_probe_group_container ()
+{
+  delete be_probe_group;
+  delete dwarf_probe_group;
+  delete hrtimer_probe_group;
+  delete mark_probe_group;
+  delete never_probe_group;
+  delete profile_probe_group;
+  delete timer_probe_group;
+}
+
+
+void
+derived_probe_group_container::register_probe(be_derived_probe* p)
+{
+  probes.push_back (p);
+  be_probe_group->register_probe(p);
+}
+
+
+void
+derived_probe_group_container::register_probe(dwarf_derived_probe* p)
+{
+  probes.push_back (p);
+  dwarf_probe_group->register_probe(p);
+}
+
+
+void
+derived_probe_group_container::register_probe(hrtimer_derived_probe* p)
+{
+  probes.push_back (p);
+  hrtimer_probe_group->register_probe(p);
+}
+
+
+void
+derived_probe_group_container::register_probe(mark_derived_probe* p)
+{
+  probes.push_back (p);
+  mark_probe_group->register_probe(p);
+}
+
+
+void
+derived_probe_group_container::register_probe(never_derived_probe* p)
+{
+  probes.push_back (p);
+  never_probe_group->register_probe(p);
+}
+
+
+void
+derived_probe_group_container::register_probe(profile_derived_probe* p)
+{
+  probes.push_back (p);
+  profile_probe_group->register_probe(p);
+}
+
+
+void
+derived_probe_group_container::register_probe(timer_derived_probe* p)
+{
+  probes.push_back (p);
+  timer_probe_group->register_probe(p);
+}
+
+
+void
+derived_probe_group_container::emit_probes (translator_output* op,
+					    unparser* up)
+{
+  // Sanity check.
+  size_t groups_size = be_probe_group->size ()
+      + dwarf_probe_group->size ()
+      + hrtimer_probe_group->size ()
+      + mark_probe_group->size ()
+      + never_probe_group->size ()
+      + profile_probe_group->size ()
+      + timer_probe_group->size ();
+  if (probes.size () != groups_size)
+    {
+      cerr << "There are " << probes.size () << " total probes, and "
+	   << groups_size << " grouped probes\n";
+
+      throw runtime_error("internal probe mismatch");
+    }
+
+  // Let each probe group emit its probes.
+  be_probe_group->emit_probes (op, up);
+  dwarf_probe_group->emit_probes (op, up);
+  hrtimer_probe_group->emit_probes (op, up);
+  mark_probe_group->emit_probes (op, up);
+  never_probe_group->emit_probes (op, up);
+  profile_probe_group->emit_probes (op, up);
+  timer_probe_group->emit_probes (op, up);
+}
Index: translate.cxx
===================================================================
RCS file: /cvs/systemtap/src/translate.cxx,v
retrieving revision 1.128
diff -u -p -r1.128 translate.cxx
--- translate.cxx	10 Aug 2006 19:19:06 -0000	1.128
+++ translate.cxx	18 Aug 2006 19:18:46 -0000
@@ -11,6 +11,7 @@
 #include "staptree.h"
 #include "elaborate.h"
 #include "translate.h"
+#include "session.h"
 #include <iostream>
 #include <set>
 #include <sstream>
@@ -3926,11 +3927,7 @@ translate_pass (systemtap_session& s)
 	  s.up->emit_function (s.functions[i]);
 	}
 
-      for (unsigned i=0; i<s.probes.size(); i++)
-        {
-          s.op->newline();
-          s.up->emit_probe (s.probes[i]);
-        }
+      s.probes.emit_probes (s.op, s.up);
 
       s.op->newline();
       s.up->emit_module_init ();

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]