tapset-been.cxx - systemtap
Data types defined
Functions defined
Source code
#include "session.h"
#include "tapsets.h"
#include "translate.h"
#include "util.h"
#include <algorithm>
#include <string>
using namespace std;
using namespace __gnu_cxx;
static const string TOK_BEGIN("begin");
static const string TOK_END("end");
static const string TOK_ERROR("error");
static const string TOK_NEVER("never");
enum be_t { BEGIN, END, ERROR };
struct be_derived_probe: public derived_probe
{
be_t type;
int64_t priority;
be_derived_probe (probe* p, probe_point* l, be_t t, int64_t pr):
derived_probe (p, l), type (t), priority (pr) {}
void join_group (systemtap_session& s);
static inline bool comp(be_derived_probe const *a,
be_derived_probe const *b)
{
return a->priority < b->priority;
}
void emit_privilege_assertion (translator_output*) {}
void print_dupe_stamp(ostream& o) { print_dupe_stamp_unprivileged (o); }
bool needs_global_locks () { return false; }
};
struct be_derived_probe_group: public generic_dpg<be_derived_probe>
{
public:
void emit_module_decls (systemtap_session& s);
void emit_module_init (systemtap_session& s);
void emit_module_exit (systemtap_session& s);
};
struct be_builder: public derived_probe_builder
{
be_t type;
be_builder(be_t t) : type(t) {}
virtual void build(systemtap_session &,
probe * base,
probe_point * location,
literal_map_t const & parameters,
vector<derived_probe *> & finished_results)
{
int64_t priority = 0;
if (type == BEGIN)
get_param(parameters, TOK_BEGIN, priority);
else if (type == END)
get_param(parameters, TOK_END, priority);
else if (type == ERROR)
get_param(parameters, TOK_ERROR, priority);
finished_results.push_back
(new be_derived_probe(base, location, type, priority));
}
};
void
be_derived_probe::join_group (systemtap_session& s)
{
if (! s.be_derived_probes)
s.be_derived_probes = new be_derived_probe_group ();
s.be_derived_probes->enroll (this);
this->group = s.be_derived_probes;
}
void
be_derived_probe_group::emit_module_decls (systemtap_session& s)
{
if (probes.empty()) return;
map<be_t, const char *> states;
states[BEGIN] = "STAP_SESSION_STARTING";
states[END] = "STAP_SESSION_STOPPING";
states[ERROR] = "STAP_SESSION_ERROR";
s.op->newline() << "/* ---- begin/end/error probes ---- */";
sort(probes.begin(), probes.end(), be_derived_probe::comp);
s.op->newline() << "static struct stap_be_probe {";
s.op->newline(1) << "const struct stap_probe * const probe;";
s.op->newline() << "int state, type;";
s.op->newline(-1) << "} stap_be_probes[] = {";
s.op->indent(1);
for (unsigned i=0; i < probes.size(); i++)
{
s.op->newline () << "{";
s.op->line() << " .probe=" << common_probe_init (probes[i]) << ",";
s.op->line() << " .state=" << states[probes[i]->type] << ",";
s.op->line() << " .type=" << probes[i]->type;
s.op->line() << " },";
}
s.op->newline(-1) << "};";
s.op->newline() << "static void enter_be_probe (struct stap_be_probe *stp) {";
s.op->indent(1);
common_probe_entryfn_prologue (s, "stp->state", "stp->probe",
"stp_probe_type_been", false);
s.op->newline() << "(*stp->probe->ph) (c);";
common_probe_entryfn_epilogue (s, false, otf_safe_context(s));
s.op->newline(-1) << "}";
}
void
be_derived_probe_group::emit_module_init (systemtap_session& s)
{
if (probes.empty()) return;
s.op->newline() << "for (i=0; i<" << probes.size() << "; i++) {";
s.op->newline(1) << "struct stap_be_probe* stp = & stap_be_probes [i];";
s.op->newline() << "if (stp->type == " << BEGIN << ")";
s.op->newline(1) << "enter_be_probe (stp); /* rc = 0 */";
s.op->newline(-2) << "}";
}
void
be_derived_probe_group::emit_module_exit (systemtap_session& s)
{
if (probes.empty()) return;
s.op->newline() << "for (i=0; i<" << probes.size() << "; i++) {";
s.op->newline(1) << "struct stap_be_probe* stp = & stap_be_probes [i];";
s.op->newline() << "if (stp->type == " << END << ")";
s.op->newline(1) << "enter_be_probe (stp);";
s.op->newline(-2) << "}";
s.op->newline() << "for (i=0; i<" << probes.size() << "; i++) {";
s.op->newline(1) << "struct stap_be_probe* stp = & stap_be_probes [i];";
s.op->newline() << "if (stp->type == " << ERROR << ")";
s.op->newline(1) << "enter_be_probe (stp);";
s.op->newline(-2) << "}";
}
struct never_derived_probe: public derived_probe
{
never_derived_probe (probe* p, probe_point* l): derived_probe (p, l) {}
void join_group (systemtap_session&) { }
void emit_privilege_assertion (translator_output*) {}
void print_dupe_stamp(ostream& o) { print_dupe_stamp_unprivileged (o); }
};
struct never_builder: public derived_probe_builder
{
never_builder() {}
virtual void build(systemtap_session &,
probe * base,
probe_point * location,
literal_map_t const &,
vector<derived_probe *> & finished_results)
{
finished_results.push_back(new never_derived_probe(base, location));
}
};
void
register_tapset_been(systemtap_session& s)
{
match_node* root = s.pattern_root;
root->bind(TOK_BEGIN)
->bind_privilege(pr_all)
->bind(new be_builder(BEGIN));
root->bind_num(TOK_BEGIN)
->bind_privilege(pr_all)
->bind(new be_builder(BEGIN));
root->bind(TOK_END)
->bind_privilege(pr_all)
->bind(new be_builder(END));
root->bind_num(TOK_END)
->bind_privilege(pr_all)
->bind(new be_builder(END));
root->bind(TOK_ERROR)
->bind_privilege(pr_all)
->bind(new be_builder(ERROR));
root->bind_num(TOK_ERROR)
->bind_privilege(pr_all)
->bind(new be_builder(ERROR));
root->bind(TOK_NEVER)
->bind_privilege(pr_all)
->bind(new never_builder());
}