summaryrefslogtreecommitdiffstats
path: root/tapsets.cxx
diff options
context:
space:
mode:
authordsmith <dsmith>2007-03-21 19:54:14 +0000
committerdsmith <dsmith>2007-03-21 19:54:14 +0000
commit29fdb4e446261de732f2edfe76823041c3e03663 (patch)
treee10ee804d9989bf034a148d8229fb79e80d4f3bf /tapsets.cxx
parentc45f6fbff2e7e32b1b9cd4c6e726fa202a4542cf (diff)
downloadsystemtap-steved-29fdb4e446261de732f2edfe76823041c3e03663.tar.gz
systemtap-steved-29fdb4e446261de732f2edfe76823041c3e03663.tar.xz
systemtap-steved-29fdb4e446261de732f2edfe76823041c3e03663.zip
2007-03-21 David Smith <dsmith@redhat.com>
PR 4146 * tapsets.cxx (common_probe_entryfn_prologue): Added 'interruptible' parameter. If a probe is interruptible, interrupts are not disabled while the probe executes. Preemption is disabled however. Interruptible parameter defaults to false. (common_probe_entryfn_epilogue): Ditto. (be_derived_probe_group::emit_module_decl): Uses new 'interruptible' parameter to mark begin/end probes as interruptible. (probe_derived_probe_group::emit_module): Initialize 'actionremaining' with MAXACTION instead of initializing 'actioncount' with 0. * translate.cxx (emit_common_header): Renamed 'actioncount' to 'actionremaining'. Turned logic around to initialize actionremaining to MAXACTION or MAXACTION_INTERRUPTIBLE then decrement it as actions occur. (translate_pass): Added MAXACTION_INTERRUPTIBLE initialization. * translate.h: Removed outdated comment portion. * stap.1.in: Documented MAXACTION_INTERRUPTIBLE. * NEWS: Added note about begin/end probes being run with interrupts enabled.
Diffstat (limited to 'tapsets.cxx')
-rw-r--r--tapsets.cxx34
1 files changed, 23 insertions, 11 deletions
diff --git a/tapsets.cxx b/tapsets.cxx
index 78d47dc7..0dddc33a 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -129,10 +129,12 @@ be_derived_probe::join_group (systemtap_session& s)
// ------------------------------------------------------------------------
void
common_probe_entryfn_prologue (translator_output* o, string statestr,
- bool overload_processing = true)
+ bool overload_processing = true,
+ bool interruptible = false)
{
o->newline() << "struct context* __restrict__ c;";
- o->newline() << "unsigned long flags;";
+ if (! interruptible)
+ o->newline() << "unsigned long flags;";
if (overload_processing)
o->newline() << "#if defined(STP_TIMING) || defined(STP_OVERLOAD)";
@@ -150,7 +152,10 @@ common_probe_entryfn_prologue (translator_output* o, string statestr,
o->newline() << "static int _pfm_num_pmd_x;";
#endif
- o->newline() << "local_irq_save (flags);";
+ if (! interruptible)
+ o->newline() << "local_irq_save (flags);";
+ else
+ o->newline() << "preempt_disable ();";
// Check for enough free enough stack space
o->newline() << "if (unlikely ((((unsigned long) (& c)) & (THREAD_SIZE-1))"; // free space
@@ -185,7 +190,10 @@ common_probe_entryfn_prologue (translator_output* o, string statestr,
o->newline() << "c->regs = 0;";
o->newline() << "c->pi = 0;";
o->newline() << "c->probe_point = 0;";
- o->newline() << "c->actioncount = 0;";
+ if (! interruptible)
+ o->newline() << "c->actionremaining = MAXACTION;";
+ else
+ o->newline() << "c->actionremaining = MAXACTION_INTERRUPTIBLE;";
o->newline() << "#ifdef STP_TIMING";
o->newline() << "c->statp = 0;";
o->newline() << "#endif";
@@ -194,7 +202,8 @@ common_probe_entryfn_prologue (translator_output* o, string statestr,
void
common_probe_entryfn_epilogue (translator_output* o,
- bool overload_processing = true)
+ bool overload_processing = true,
+ bool interruptible = false)
{
if (overload_processing)
o->newline() << "#if defined(STP_TIMING) || defined(STP_OVERLOAD)";
@@ -262,7 +271,10 @@ common_probe_entryfn_epilogue (translator_output* o,
o->newline(-1) << "probe_epilogue:"; // context is free
o->indent(1);
- o->newline() << "local_irq_restore (flags);";
+ if (! interruptible)
+ o->newline() << "local_irq_restore (flags);";
+ else
+ o->newline() << "preempt_enable_no_resched ();";
}
@@ -276,17 +288,17 @@ be_derived_probe_group::emit_module_decls (systemtap_session& s)
s.op->newline() << "/* ---- begin/end probes ---- */";
s.op->newline() << "void enter_begin_probe (void (*fn)(struct context*)) {";
s.op->indent(1);
- common_probe_entryfn_prologue (s.op, "STAP_SESSION_STARTING", false);
+ common_probe_entryfn_prologue (s.op, "STAP_SESSION_STARTING", false, true);
s.op->newline() << "c->probe_point = \"begin\";";
s.op->newline() << "(*fn) (c);";
- common_probe_entryfn_epilogue (s.op, false);
+ common_probe_entryfn_epilogue (s.op, false, true);
s.op->newline(-1) << "}";
s.op->newline() << "void enter_end_probe (void (*fn)(struct context*)) {";
s.op->indent(1);
- common_probe_entryfn_prologue (s.op, "STAP_SESSION_STOPPING", false);
+ common_probe_entryfn_prologue (s.op, "STAP_SESSION_STOPPING", false, true);
s.op->newline() << "c->probe_point = \"end\";";
s.op->newline() << "(*fn) (c);";
- common_probe_entryfn_epilogue (s.op, false);
+ common_probe_entryfn_epilogue (s.op, false, true);
s.op->newline(-1) << "}";
}
@@ -4130,7 +4142,7 @@ profile_derived_probe_group::emit_module_decls (systemtap_session& s)
{
// Some lightweight inter-probe context resetting
// XXX: not quite right: MAXERRORS not respected
- s.op->newline() << "c->actioncount = 0;";
+ s.op->newline() << "c->actionremaining = MAXACTION;";
}
s.op->newline() << "if (c->last_error == NULL) " << probes[i]->name << " (c);";
}