LCOV - code coverage report
Current view: top level - mnt/wasteland/wcohen/systemtap_write/systemtap - tapset-perfmon.cxx (source / functions) Hit Total Coverage
Test: stap.info Lines: 216 226 95.6 %
Date: 2013-03-08 Functions: 14 21 66.7 %
Branches: 238 470 50.6 %

           Branch data     Line data    Source code
       1                 :            : // tapset for HW performance monitoring
       2                 :            : // Copyright (C) 2005-2013 Red Hat Inc.
       3                 :            : // Copyright (C) 2005-2007 Intel Corporation.
       4                 :            : //
       5                 :            : // This file is part of systemtap, and is free software.  You can
       6                 :            : // redistribute it and/or modify it under the terms of the GNU General
       7                 :            : // Public License (GPL); either version 2, or (at your option) any
       8                 :            : // later version.
       9                 :            : 
      10                 :            : #include "session.h"
      11                 :            : #include "tapsets.h"
      12                 :            : #include "task_finder.h"
      13                 :            : #include "translate.h"
      14                 :            : #include "util.h"
      15                 :            : 
      16                 :            : #include <string>
      17                 :            : #include <wordexp.h>
      18                 :            : 
      19                 :            : extern "C" {
      20                 :            : #define __STDC_FORMAT_MACROS
      21                 :            : #include <inttypes.h>
      22                 :            : }
      23                 :            : 
      24                 :            : using namespace std;
      25                 :            : using namespace __gnu_cxx;
      26                 :            : 
      27                 :            : 
      28         [ +  - ]:       2414 : static const string TOK_PERF("perf");
      29         [ +  - ]:       2414 : static const string TOK_TYPE("type");
      30         [ +  - ]:       2414 : static const string TOK_CONFIG("config");
      31         [ +  - ]:       2414 : static const string TOK_SAMPLE("sample");
      32         [ +  - ]:       2414 : static const string TOK_PROCESS("process");
      33         [ +  - ]:       2414 : static const string TOK_COUNTER("counter");
      34                 :            : 
      35                 :            : 
      36                 :            : // ------------------------------------------------------------------------
      37                 :            : // perf event derived probes
      38                 :            : // ------------------------------------------------------------------------
      39                 :            : // This is a new interface to the perfmon hw.
      40                 :            : //
      41                 :            : 
      42 [ #  # ][ #  # ]:          0 : struct perf_derived_probe: public derived_probe
                 [ #  # ]
      43                 :            : {
      44                 :            :   int64_t event_type;
      45                 :            :   int64_t event_config;
      46                 :            :   int64_t interval;
      47                 :            :   bool has_process;
      48                 :            :   bool has_counter;
      49                 :            :   string process_name;
      50                 :            :   string counter;
      51                 :            :   perf_derived_probe (probe* p, probe_point* l, int64_t type, int64_t config,
      52                 :            :                       int64_t i, bool pp, bool cp, string pn, string cv);
      53                 :            :   virtual void join_group (systemtap_session& s);
      54                 :            : };
      55                 :            : 
      56                 :            : 
      57         [ #  # ]:         14 : struct perf_derived_probe_group: public generic_dpg<perf_derived_probe>
      58                 :            : {
      59                 :            :   void emit_module_decls (systemtap_session& s);
      60                 :            :   void emit_module_init (systemtap_session& s);
      61                 :            :   void emit_module_exit (systemtap_session& s);
      62                 :            : };
      63                 :            : 
      64                 :            : 
      65                 :         94 : perf_derived_probe::perf_derived_probe (probe* p, probe_point* l,
      66                 :            :                                         int64_t type,
      67                 :            :                                         int64_t config,
      68                 :            :                                         int64_t i,
      69                 :            :                                         bool process_p,
      70                 :            :                                         bool counter_p,
      71                 :            :                                         string process_n,
      72                 :            :                                         string counter):
      73                 :            :   
      74                 :            :   derived_probe (p, l, true /* .components soon rewritten */),
      75                 :            :   event_type (type), event_config (config), interval (i),
      76                 :            :   has_process (process_p), has_counter (counter_p), process_name (process_n),
      77 [ +  - ][ +  - ]:         94 :   counter (counter)
      78                 :            : {
      79         [ +  - ]:         94 :   vector<probe_point::component*>& comps = this->sole_location()->components;
      80         [ +  - ]:         94 :   comps.clear();
      81 [ +  - ][ +  - ]:         94 :   comps.push_back (new probe_point::component (TOK_PERF));
                 [ +  - ]
      82 [ +  - ][ +  - ]:         94 :   comps.push_back (new probe_point::component (TOK_TYPE, new literal_number(type)));
         [ +  - ][ +  - ]
                 [ +  - ]
      83 [ +  - ][ +  - ]:         94 :   comps.push_back (new probe_point::component (TOK_CONFIG, new literal_number (config)));
         [ +  - ][ +  - ]
                 [ +  - ]
      84 [ +  - ][ +  - ]:         94 :   comps.push_back (new probe_point::component (TOK_SAMPLE, new literal_number (interval)));
         [ +  - ][ +  - ]
                 [ +  - ]
      85 [ +  - ][ +  - ]:         94 :   comps.push_back (new probe_point::component (TOK_PROCESS, new literal_string (process_name)));
         [ +  - ][ +  - ]
                 [ +  - ]
      86 [ +  - ][ +  - ]:         94 :   comps.push_back (new probe_point::component (TOK_COUNTER, new literal_string (counter)));
         [ +  - ][ +  - ]
                 [ +  - ]
      87                 :         94 : }
      88                 :            : 
      89                 :            : 
      90                 :            : void
      91                 :         94 : perf_derived_probe::join_group (systemtap_session& s)
      92                 :            : {
      93         [ +  + ]:         94 :   if (! s.perf_derived_probes)
      94         [ +  - ]:         14 :     s.perf_derived_probes = new perf_derived_probe_group ();
      95                 :         94 :   s.perf_derived_probes->enroll (this);
      96                 :            : 
      97 [ +  + ][ +  + ]:         94 :   if (has_process && !has_counter)
      98                 :          3 :     enable_task_finder(s);
      99                 :         94 : }
     100                 :            : 
     101                 :            : 
     102                 :            : void
     103                 :          8 : perf_derived_probe_group::emit_module_decls (systemtap_session& s)
     104                 :            : {
     105                 :          8 :   bool have_a_process_tag = false;
     106                 :            : 
     107         [ +  + ]:         92 :   for (unsigned i=0; i < probes.size(); i++)
     108 [ +  + ][ +  - ]:         86 :     if (probes[i]->has_process && !probes[i]->has_counter)
                 [ +  + ]
     109                 :            :       {
     110                 :          2 :         have_a_process_tag = true;
     111                 :          2 :         break;
     112                 :            :       }
     113                 :            : 
     114         [ -  + ]:         16 :   if (probes.empty()) return;
     115                 :            : 
     116                 :          8 :   s.op->newline() << "/* ---- perf probes ---- */";
     117                 :          8 :   s.op->newline() << "#include <linux/perf_event.h>";
     118                 :          8 :   s.op->newline() << "#include \"linux/perf.h\"";
     119                 :          8 :   s.op->newline();
     120                 :            : 
     121                 :            :   /* declarations */
     122                 :          8 :   s.op->newline() << "static void handle_perf_probe (unsigned i, struct pt_regs *regs);";
     123         [ +  + ]:         95 :   for (unsigned i=0; i < probes.size(); i++)
     124                 :            :     {
     125                 :         87 :       s.op->newline() << "#ifdef STAPCONF_PERF_HANDLER_NMI";
     126                 :         87 :       s.op->newline() << "static void enter_perf_probe_" << i
     127                 :         87 :                       << " (struct perf_event *e, int nmi, "
     128                 :         87 :                       << "struct perf_sample_data *data, "
     129                 :         87 :                       << "struct pt_regs *regs);";
     130                 :         87 :       s.op->newline() << "#else";
     131                 :         87 :       s.op->newline() << "static void enter_perf_probe_" << i
     132                 :         87 :                       << " (struct perf_event *e, "
     133                 :         87 :                       << "struct perf_sample_data *data, "
     134                 :         87 :                       << "struct pt_regs *regs);";
     135                 :         87 :       s.op->newline() << "#endif";
     136                 :            :     }
     137                 :          8 :   s.op->newline();
     138                 :            : 
     139                 :            :   // Output task finder callback routine
     140         [ +  + ]:          8 :   if (have_a_process_tag)
     141                 :            :     {
     142                 :          2 :       s.op->newline() << "static int _stp_perf_probe_cb(struct stap_task_finder_target *tgt, struct task_struct *tsk, int register_p, int process_p) {";
     143                 :          2 :       s.op->indent(1);
     144                 :          2 :       s.op->newline() << "int rc = 0;";
     145                 :          2 :       s.op->newline() << "struct stap_perf_probe *p = container_of(tgt, struct stap_perf_probe, e.t.tgt);";
     146                 :            :       
     147                 :          2 :       s.op->newline() << "if (register_p) ";
     148                 :          2 :       s.op->indent(1);
     149                 :            :       
     150                 :          2 :       s.op->newline() << "rc = _stp_perf_init(p, tsk);";
     151                 :          2 :       s.op->newline(-1) << "else";
     152                 :          2 :       s.op->newline(1) << "_stp_perf_del(p);";
     153                 :          2 :       s.op->newline(-1) << "return rc;";
     154                 :          2 :       s.op->newline(-1) << "}";
     155                 :            :     }
     156                 :            : 
     157                 :            :   /* data structures */
     158                 :          8 :   s.op->newline() << "static struct stap_perf_probe stap_perf_probes ["
     159                 :          8 :                   << probes.size() << "] = {";
     160                 :          8 :   s.op->indent(1);
     161         [ +  + ]:         95 :   for (unsigned i=0; i < probes.size(); i++)
     162                 :            :     {
     163 [ +  - ][ +  - ]:         87 :       s.op->newline() << "{";
     164 [ +  - ][ +  - ]:         87 :       s.op->newline(1) << ".attr={ "
     165 [ +  - ][ +  - ]:         87 :                        << ".type=" << probes[i]->event_type << "ULL, "
                 [ +  - ]
     166 [ +  - ][ +  - ]:         87 :                        << ".config=" << probes[i]->event_config << "ULL, "
                 [ +  - ]
     167 [ +  - ][ +  - ]:         87 :                        << "{ .sample_period=" << probes[i]->interval << "ULL }},";
                 [ +  - ]
     168 [ +  - ][ +  - ]:         87 :       s.op->newline() << ".callback=enter_perf_probe_" << i << ", ";
         [ +  - ][ +  - ]
     169 [ +  - ][ +  - ]:         87 :       s.op->newline() << ".probe=" << common_probe_init (probes[i]) << ", ";
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
     170                 :            : 
     171         [ +  - ]:         87 :       string l_process_name;
     172 [ +  + ][ +  - ]:         87 :       if (probes[i]->has_process && !probes[i]->has_counter)
                 [ +  + ]
     173                 :            :         {
     174 [ +  - ][ +  + ]:          3 :           if (probes[i]->process_name.length() == 0)
     175                 :            :             {
     176                 :            :               wordexp_t words;
     177 [ +  - ][ +  - ]:          1 :               int rc = wordexp(s.cmd.c_str(), &words, WRDE_NOCMD|WRDE_UNDEF);
     178 [ +  - ][ -  + ]:          1 :               if (rc || words.we_wordc <= 0)
     179 [ #  # ][ #  # ]:          0 :                 throw semantic_error(_("unspecified process probe is invalid without a -c COMMAND"));
     180         [ +  - ]:          1 :               l_process_name = words.we_wordv[0];
     181                 :          1 :               wordfree (& words);
     182                 :            :             }
     183                 :            :           else
     184         [ +  - ]:          2 :             l_process_name = probes[i]->process_name;
     185                 :            : 
     186 [ +  - ][ +  - ]:          3 :           s.op->line() << " .e={";
     187 [ +  - ][ +  - ]:          3 :           s.op->line() << " .t={";
     188 [ +  - ][ +  - ]:          3 :           s.op->line() << " .tgt={";
     189 [ +  - ][ +  - ]:          3 :           s.op->line() << " .purpose=\"perfctr\",";
     190 [ +  - ][ +  - ]:          3 :           s.op->line() << " .procname=\"" << l_process_name << "\",";
         [ +  - ][ +  - ]
     191 [ +  - ][ +  - ]:          3 :           s.op->line() << " .pid=0,";
     192 [ +  - ][ +  - ]:          3 :           s.op->line() << " .callback=&_stp_perf_probe_cb,";
     193 [ +  - ][ +  - ]:          3 :           s.op->line() << " },";
     194 [ +  - ][ +  - ]:          3 :           s.op->line() << " },";
     195 [ +  - ][ +  - ]:          3 :           s.op->line() << " },";
     196 [ +  - ][ +  - ]:          3 :           s.op->newline() << ".per_thread=" << "1, ";
                 [ +  - ]
     197                 :            :         }
     198         [ +  + ]:         84 :       else if (probes[i]->has_counter)
     199 [ +  - ][ +  - ]:          1 :         s.op->newline() << ".per_thread=" << "1, ";
                 [ +  - ]
     200                 :            :       else
     201 [ +  - ][ +  - ]:         83 :         s.op->newline() << ".per_thread=" << "0, ";
                 [ +  - ]
     202 [ +  - ][ +  - ]:         87 :       s.op->newline(-1) << "},";
     203         [ +  - ]:         87 :     }
     204                 :          8 :   s.op->newline(-1) << "};";
     205                 :          8 :   s.op->newline();
     206                 :            : 
     207                 :            :   /* wrapper functions */
     208         [ +  + ]:         95 :   for (unsigned i=0; i < probes.size(); i++)
     209                 :            :     {
     210                 :         87 :       s.op->newline() << "#ifdef STAPCONF_PERF_HANDLER_NMI";
     211                 :         87 :       s.op->newline() << "static void enter_perf_probe_" << i
     212                 :         87 :                       << " (struct perf_event *e, int nmi, "
     213                 :         87 :                       << "struct perf_sample_data *data, "
     214                 :         87 :                       << "struct pt_regs *regs)";
     215                 :         87 :       s.op->newline() << "#else";
     216                 :         87 :       s.op->newline() << "static void enter_perf_probe_" << i
     217                 :         87 :                       << " (struct perf_event *e, "
     218                 :         87 :                       << "struct perf_sample_data *data, "
     219                 :         87 :                       << "struct pt_regs *regs)";
     220                 :         87 :       s.op->newline() << "#endif";
     221                 :         87 :       s.op->newline() << "{";
     222                 :         87 :       s.op->newline(1) << "handle_perf_probe(" << i << ", regs);";
     223                 :         87 :       s.op->newline(-1) << "}";
     224                 :            :     }
     225                 :          8 :   s.op->newline();
     226                 :            : 
     227                 :          8 :   s.op->newline() << "static void handle_perf_probe (unsigned i, struct pt_regs *regs)";
     228                 :          8 :   s.op->newline() << "{";
     229                 :          8 :   s.op->newline(1) << "struct stap_perf_probe* stp = & stap_perf_probes [i];";
     230                 :            :   common_probe_entryfn_prologue (s, "STAP_SESSION_RUNNING", "stp->probe",
     231 [ +  - ][ +  - ]:          8 :                                  "stp_probe_type_perf");
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
                 [ +  - ]
     232                 :          8 :   s.op->newline() << "if (user_mode(regs)) {";
     233                 :          8 :   s.op->newline(1)<< "c->user_mode_p = 1;";
     234                 :          8 :   s.op->newline() << "c->uregs = regs;";
     235                 :          8 :   s.op->newline(-1) << "} else {";
     236                 :          8 :   s.op->newline(1) << "c->kregs = regs;";
     237                 :          8 :   s.op->newline(-1) << "}";
     238                 :            : 
     239                 :          8 :   s.op->newline() << "(*stp->probe->ph) (c);";
     240                 :          8 :   common_probe_entryfn_epilogue (s, true);
     241                 :          8 :   s.op->newline(-1) << "}";
     242                 :          8 :   s.op->newline();
     243                 :          8 :   s.op->newline() << "#include \"linux/perf.c\"";
     244                 :          8 :   s.op->newline();
     245                 :            : }
     246                 :            : 
     247                 :            : 
     248                 :            : void
     249                 :          8 : perf_derived_probe_group::emit_module_init (systemtap_session& s)
     250                 :            : {
     251                 :          8 :   bool have_a_process_tag = false;
     252                 :            :   
     253         [ +  + ]:         92 :   for (unsigned i=0; i < probes.size(); i++)
     254         [ +  + ]:         86 :     if (probes[i]->has_process)
     255                 :            :       {
     256                 :          2 :         have_a_process_tag = true;
     257                 :          2 :         break;
     258                 :            :       }
     259                 :            : 
     260         [ -  + ]:         16 :   if (probes.empty()) return;
     261                 :            : 
     262                 :          8 :   s.op->newline() << "for (i=0; i<" << probes.size() << "; i++) {";
     263                 :          8 :   s.op->newline(1) << "struct stap_perf_probe* stp = & stap_perf_probes [i];";
     264                 :          8 :   s.op->newline() << "rc = _stp_perf_init(stp, 0);";
     265                 :          8 :   s.op->newline() << "if (rc) {";
     266                 :          8 :   s.op->newline(1) << "probe_point = stp->probe->pp;";
     267                 :          8 :   s.op->newline() << "for (j=0; j<i; j++) {";
     268                 :          8 :   s.op->newline(1) << "_stp_perf_del(& stap_perf_probes [j]);";
     269                 :          8 :   s.op->newline(-1) << "}"; // for unwind loop
     270                 :          8 :   s.op->newline() << "break;";
     271                 :          8 :   s.op->newline(-1) << "}"; // if-error
     272         [ +  + ]:          8 :   if (have_a_process_tag)
     273                 :          2 :     s.op->newline() << "rc = stap_register_task_finder_target(&stp->e.t.tgt);";
     274                 :          8 :   s.op->newline(-1) << "}"; // for loop
     275                 :            : }
     276                 :            : 
     277                 :            : 
     278                 :            : void
     279                 :         15 : perf_derived_probe_group::emit_module_exit (systemtap_session& s)
     280                 :            : {
     281         [ -  + ]:         30 :   if (probes.empty()) return;
     282                 :            : 
     283                 :         15 :   s.op->newline() << "for (i=0; i<" << probes.size() << "; i++) {";
     284                 :         15 :   s.op->newline(1) << "_stp_perf_del(& stap_perf_probes [i]);";
     285                 :         15 :   s.op->newline(-1) << "}"; // for loop
     286                 :            : }
     287                 :            : 
     288                 :            : 
     289         [ #  # ]:       1218 : struct perf_builder: public derived_probe_builder
     290                 :            : {
     291                 :            :     virtual void build(systemtap_session & sess,
     292                 :            :                        probe * base, probe_point * location,
     293                 :            :                        literal_map_t const & parameters,
     294                 :            :                        vector<derived_probe *> & finished_results);
     295                 :            : 
     296                 :            :     static void register_patterns(systemtap_session& s);
     297                 :            : };
     298                 :            : 
     299                 :            : 
     300         [ -  + ]:          7 : struct statement_counter: public update_visitor
     301                 :            : {
     302                 :            :   bool empty;
     303                 :            :   const token* first_tok;
     304                 :            : 
     305                 :          7 :   statement_counter () {}
     306                 :            : 
     307                 :          7 :   void visit_block (block *b)
     308                 :            :   {
     309         [ +  - ]:          7 :     if (b->statements.size() > 0)
     310                 :            :       {
     311                 :          7 :         empty = false;
     312                 :          7 :         first_tok = b->statements[0]->tok;
     313                 :            :       }
     314                 :            :     else
     315                 :          0 :       empty = true;
     316                 :          7 :   };
     317                 :            : };
     318                 :            :   
     319                 :            : 
     320                 :            : void
     321                 :         95 : perf_builder::build(systemtap_session & sess,
     322                 :            :                     probe * base,
     323                 :            :                     probe_point * location,
     324                 :            :                     literal_map_t const & parameters,
     325                 :            :                     vector<derived_probe *> & finished_results)
     326                 :            : {
     327                 :            :   // XXX need additional version checks too?
     328                 :            :   // --- perhaps look for export of perf_event_create_kernel_counter
     329 [ +  - ][ +  - ]:         95 :   if (sess.kernel_exports.find("perf_event_create_kernel_counter") == sess.kernel_exports.end())
         [ +  - ][ +  - ]
                 [ -  + ]
     330 [ #  # ][ #  # ]:          0 :     throw semantic_error (_("perf probes not available without exported perf_event_create_kernel_counter"));
     331 [ +  - ][ +  - ]:         95 :   if (sess.kernel_config["CONFIG_PERF_EVENTS"] != "y")
         [ +  - ][ +  - ]
                 [ -  + ]
     332 [ #  # ][ #  # ]:          0 :     throw semantic_error (_("perf probes not available without CONFIG_PERF_EVENTS"));
     333                 :            : 
     334                 :            :   int64_t type;
     335         [ +  - ]:         95 :   bool has_type = get_param(parameters, TOK_TYPE, type);
     336         [ -  + ]:         95 :   assert(has_type);
     337                 :            : 
     338                 :            :   int64_t config;
     339         [ +  - ]:         95 :   bool has_config = get_param(parameters, TOK_CONFIG, config);
     340         [ -  + ]:         95 :   assert(has_config);
     341                 :            : 
     342                 :            :   int64_t period;
     343         [ +  - ]:         95 :   bool has_period = get_param(parameters, TOK_SAMPLE, period);
     344         [ +  - ]:         95 :   if (!has_period)
     345                 :         95 :     period = 1000000; // XXX: better parametrize this default
     346         [ #  # ]:          0 :   else if (period < 1)
     347                 :          0 :     throw semantic_error(_("invalid perf sample period ") + lex_cast(period),
     348 [ #  # ][ #  # ]:          0 :                          parameters.find(TOK_SAMPLE)->second->tok);
         [ #  # ][ #  # ]
                 [ #  # ]
     349                 :            :   bool proc_p;
     350         [ +  - ]:         95 :   string proc_n;
     351         [ +  - ]:         95 :   proc_p = has_null_param(parameters, TOK_PROCESS)
     352 [ +  + ][ +  - ]:         95 :     || get_param(parameters, TOK_PROCESS, proc_n);
                 [ +  + ]
     353         [ +  + ]:         95 :   if (proc_p)
     354 [ +  - ][ +  - ]:         10 :     proc_n = find_executable (proc_n, sess.sysroot, sess.sysenv);
         [ +  - ][ +  - ]
                 [ +  - ]
     355                 :            : 
     356         [ +  - ]:         95 :   string var;
     357         [ +  - ]:         95 :   bool has_counter = get_param(parameters, TOK_COUNTER, var);
     358 [ +  - ][ -  + ]:         95 :   if (var.find_first_of("*?[") != string::npos)
     359 [ #  # ][ #  # ]:          0 :     throw semantic_error(_("wildcard not allowed with perf probe counter component"));
     360         [ +  + ]:         95 :   if (has_counter)
     361                 :            :     {
     362 [ +  - ][ +  + ]:          8 :       if (var.length() == 0)
     363 [ +  - ][ +  - ]:          1 :         throw semantic_error(_("missing perf probe counter component name"));
     364                 :            :         
     365                 :          7 :       period = 0;               // perf_event_attr.sample_freq should be 0
     366                 :          7 :       map<string, pair<string,derived_probe*> >::iterator it;
     367 [ +  - ][ +  - ]:          8 :       for (it=sess.perf_counters.begin(); it != sess.perf_counters.end(); it++)
                 [ +  + ]
     368 [ +  - ][ -  + ]:          1 :         if ((*it).first == var)
     369 [ #  # ][ #  # ]:          0 :           throw semantic_error(_("duplicate counter name"));
     370                 :            : 
     371         [ +  - ]:          7 :       struct statement_counter sc;
     372         [ +  - ]:          7 :       base->body->visit(&sc);
     373         [ +  - ]:          7 :       if (! sc.empty)
     374 [ +  - ][ +  - ]:          7 :         sess.print_warning(_("Statements in perf counter probe will never be reached."), sc.first_tok);
                 [ +  - ]
     375                 :            : 
     376 [ +  - ][ +  - ]:          7 :       if_statement *ifs = new if_statement ();
     377                 :          7 :       ifs->tok = base->tok;
     378 [ +  - ][ +  - ]:          7 :       ifs->thenblock = new next_statement ();
     379                 :          7 :       ifs->thenblock->tok = base->tok;
     380                 :          7 :       ifs->elseblock = NULL;
     381 [ +  - ][ +  - ]:          7 :       ifs->condition = new literal_number(0);
     382 [ +  - ][ +  - ]:          8 :       base->body = new block (ifs, base->body);
                 [ +  - ]
     383                 :            :     }
     384                 :            : 
     385         [ +  + ]:         94 :   if (sess.verbose > 1)
     386 [ +  - ][ +  - ]:         81 :     clog << _F("perf probe type=%" PRId64 " config=%" PRId64 " period=%" PRId64, type, config, period) << endl;
         [ +  - ][ +  - ]
     387                 :            : 
     388                 :            :   finished_results.push_back
     389                 :            :     (new perf_derived_probe(base, location, type, config, period, proc_p,
     390 [ +  - ][ +  - ]:         94 :                             has_counter, proc_n, var));
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
                 [ +  - ]
     391 [ +  - ][ +  - ]:         95 :   sess.perf_counters[var] = make_pair(proc_n,finished_results.back());
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
                 [ +  - ]
     392                 :         94 : }
     393                 :            : 
     394                 :            : 
     395                 :            : void
     396                 :       1218 : register_tapset_perf(systemtap_session& s)
     397                 :            : {
     398                 :            :   // NB: at this point, the binding is *not* unprivileged.
     399                 :            : 
     400                 :       1218 :   derived_probe_builder *builder = new perf_builder();
     401                 :       1218 :   match_node* perf = s.pattern_root->bind(TOK_PERF);
     402                 :            : 
     403                 :       1218 :   match_node* event = perf->bind_num(TOK_TYPE)->bind_num(TOK_CONFIG);
     404                 :       1218 :   event->bind(builder);
     405                 :       1218 :   event->bind_num(TOK_SAMPLE)->bind(builder);
     406                 :       1218 :   event->bind_str(TOK_PROCESS)->bind(builder);
     407                 :       1218 :   event->bind(TOK_PROCESS)->bind(builder);
     408                 :       1218 :   event->bind_str(TOK_COUNTER)->bind(builder);
     409                 :       1218 :   event->bind_str(TOK_PROCESS)->bind_str(TOK_COUNTER)->bind(builder);
     410 [ +  - ][ +  - ]:       8460 : }
     411                 :            : 
     412                 :            : /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */

Generated by: LCOV version 1.9