From 65aeaea0bc47637030ebe4c2d3a103e1fddaa8d8 Mon Sep 17 00:00:00 2001 From: fche Date: Tue, 2 Oct 2007 17:44:25 +0000 Subject: 2007-10-02 Frank Ch. Eigler PR 5078 * tapsets.cxx (be_derived_probe): Rework to add error probe support. Emit probe description array in C for traversal by generated code. * register_standard_tapsets: Add error probes. * stapprobes.5.in: Document. * translate.cxx (emit_module_init): Handle errors that may occur during begin probes. (emit_module_exit): Use schedule() rather than cpu_relax() during shutdown synchronization wait loop. * staptree.cxx (probe::printsig): Put multiple probe points on same line. 2007-10-02 Frank Ch. Eigler PR 5078 * semok/twentysix.stp, systemtap.base/beginenderror.*: New tests. --- translate.cxx | 45 ++++++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 21 deletions(-) (limited to 'translate.cxx') diff --git a/translate.cxx b/translate.cxx index 7ff2bae6..f2351b9f 100644 --- a/translate.cxx +++ b/translate.cxx @@ -1144,23 +1144,6 @@ c_unparser::emit_module_init () } o->newline() << "#endif"; - for (unsigned i=0; iemit_module_init (*session); - // NB: this gives O(N**2) amount of code, but luckily there - // are only seven or eight derived_probe_groups, so it's ok. - o->newline() << "if (rc) {"; - o->newline(1) << "_stp_error (\"probe %s registration error (rc %d)\", probe_point, rc);"; - // NB: we need to be in the error state so timers can shutdown cleanly, - // and so end probes don't run. - o->newline() << "atomic_set (&session_state, STAP_SESSION_ERROR);"; - if (i>0) - for (int j=i-1; j>=0; j--) - g[j]->emit_module_exit (*session); - o->newline() << "goto out;"; - o->newline(-1) << "}"; - } - // Print a message to the kernel log about this module. This is // intended to help debug problems with systemtap modules. o->newline() << "printk (KERN_DEBUG \"%s: " @@ -1179,9 +1162,30 @@ c_unparser::emit_module_init () << ", (unsigned long) _stp_allocated_memory" << ");"; + // Run all probe registrations. This actually runs begin probes. + + for (unsigned i=0; iemit_module_init (*session); + // NB: this gives O(N**2) amount of code, but luckily there + // are only seven or eight derived_probe_groups, so it's ok. + o->newline() << "if (rc) {"; + o->newline(1) << "_stp_error (\"probe %s registration error (rc %d)\", probe_point, rc);"; + // NB: we need to be in the error state so timers can shutdown cleanly, + // and so end probes don't run. OTOH, error probes can run. + o->newline() << "atomic_set (&session_state, STAP_SESSION_ERROR);"; + if (i>0) + for (int j=i-1; j>=0; j--) + g[j]->emit_module_exit (*session); + o->newline() << "goto out;"; + o->newline(-1) << "}"; + } + // All registrations were successful. Consider the system started. - o->newline() << "atomic_set (&session_state, STAP_SESSION_RUNNING);"; - o->newline() << "return 0;"; + o->newline() << "if (atomic_read (&session_state) == STAP_SESSION_STARTING)"; + // NB: only other valid state value is ERROR, in which case we don't + o->newline(1) << "atomic_set (&session_state, STAP_SESSION_RUNNING);"; + o->newline(-1) << "return 0;"; // Error handling path; by now all partially registered probe groups // have been unregistered. @@ -1237,8 +1241,7 @@ c_unparser::emit_module_exit () o->newline(1) << "if (cpu_possible (i) && " << "atomic_read (& ((struct context *)per_cpu_ptr(contexts, i))->busy)) " << "holdon = 1;"; - o->newline () << "cpu_relax ();"; - // o->newline(-1) << "if (holdon) msleep (5);"; + o->newline () << "schedule ();"; o->newline(-1) << "} while (holdon);"; o->newline(-1); // XXX: might like to have an escape hatch, in case some probe is -- cgit