public inbox for systemtap@sourceware.org
 help / color / mirror / Atom feed
* [Bug translator/2421] New: translator emitting duplicate probe handlers
@ 2006-03-06 14:00 fche at redhat dot com
  2006-08-10 19:19 ` [Bug translator/2421] " dsmith at redhat dot com
  0 siblings, 1 reply; 4+ messages in thread
From: fche at redhat dot com @ 2006-03-06 14:00 UTC (permalink / raw)
  To: systemtap

See http://sources.redhat.com/ml/systemtap/2006-q1/msg00705.html

The "flavour-based" dwarf_derived_probe merging code in src/tapsets.cxx should
be expandable to this scenario.

-- 
           Summary: translator emitting duplicate probe handlers
           Product: systemtap
           Version: unspecified
            Status: NEW
          Severity: normal
          Priority: P2
         Component: translator
        AssignedTo: systemtap at sources dot redhat dot com
        ReportedBy: fche at redhat dot com


http://sourceware.org/bugzilla/show_bug.cgi?id=2421

------- You are receiving this mail because: -------
You are the assignee for the bug, or are watching the assignee.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [Bug translator/2421] translator emitting duplicate probe handlers
  2006-03-06 14:00 [Bug translator/2421] New: translator emitting duplicate probe handlers fche at redhat dot com
@ 2006-08-10 19:19 ` dsmith at redhat dot com
  2006-08-10 20:18   ` Frank Ch. Eigler
  0 siblings, 1 reply; 4+ messages in thread
From: dsmith at redhat dot com @ 2006-08-10 19:19 UTC (permalink / raw)
  To: systemtap



-- 
           What    |Removed                     |Added
----------------------------------------------------------------------------
         AssignedTo|systemtap at sources dot    |dsmith at redhat dot com
                   |redhat dot com              |
             Status|NEW                         |ASSIGNED


http://sourceware.org/bugzilla/show_bug.cgi?id=2421

------- You are receiving this mail because: -------
You are the assignee for the bug, or are watching the assignee.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [Bug translator/2421] translator emitting duplicate probe handlers
  2006-08-10 19:19 ` [Bug translator/2421] " dsmith at redhat dot com
@ 2006-08-10 20:18   ` Frank Ch. Eigler
  2006-08-18 19:29     ` David Smith
  0 siblings, 1 reply; 4+ messages in thread
From: Frank Ch. Eigler @ 2006-08-10 20:18 UTC (permalink / raw)
  To: systemtap


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".

- FChE

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [Bug translator/2421] translator emitting duplicate probe  handlers
  2006-08-10 20:18   ` Frank Ch. Eigler
@ 2006-08-18 19:29     ` David Smith
  0 siblings, 0 replies; 4+ messages in thread
From: David Smith @ 2006-08-18 19:29 UTC (permalink / raw)
  To: Frank Ch. Eigler; +Cc: Systemtap List

[-- Attachment #1: Type: text/plain, Size: 2924 bytes --]

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)


[-- Attachment #2: probe_group.patch --]
[-- Type: text/x-patch, Size: 22412 bytes --]

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 ();

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2006-08-18 19:29 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-03-06 14:00 [Bug translator/2421] New: translator emitting duplicate probe handlers fche at redhat dot com
2006-08-10 19:19 ` [Bug translator/2421] " dsmith at redhat dot com
2006-08-10 20:18   ` Frank Ch. Eigler
2006-08-18 19:29     ` David Smith

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).