diff options
author | fche <fche> | 2006-01-03 22:33:53 +0000 |
---|---|---|
committer | fche <fche> | 2006-01-03 22:33:53 +0000 |
commit | 9a604face6354d63a3948a08e85613168a9dfb88 (patch) | |
tree | 3b4f269604baebeb2da9c84e973bed06202bd980 /translate.cxx | |
parent | f256184bbdab4cf63c5ad8917e5b8a31de497fb9 (diff) | |
download | systemtap-steved-9a604face6354d63a3948a08e85613168a9dfb88.tar.gz systemtap-steved-9a604face6354d63a3948a08e85613168a9dfb88.tar.xz systemtap-steved-9a604face6354d63a3948a08e85613168a9dfb88.zip |
2006-01-03 Frank Ch. Eigler <fche@redhat.com>
PR 1144, 1379
* tapsets.cxx (emit_probe_prologue, _epilogue): New routines.
Call from existing derived_probe spots. Implement soft errors in
epilogue code. Implement reentrancy detection in prologue code.
(dwarf_derived_probe::emit_deregistration): Add kprobes layer
"nmissed" to skipped_count.
* translate.cxx (varlock): Use nsleep(TRYLOCKDELAY) in lock
contention loop.
(emit_module_exit): Report number of soft errors and skipped probes.
(emit_function, _probe): Add __restrict__ marker to context pointer.
(translate_pass): Define new MAXTRYLOCK, TRYLOCKDELAY, MAXERRORS,
MAXSKIPPED parameters.
* tapset/logging.stp (error): Don't stp_error, just set context state.
* stap.1.in, stapfuncs.5.in: Document soft errors.
* elaborate.h: Corresponding changes.
2006-01-03 Frank Ch. Eigler <fche@redhat.com>
* io.c (_stp_softerror): New function.
2006-01-03 Frank Ch. Eigler <fche@redhat.com>
* systemtap.base/timers.exp: Extend the test run duration.
Accept skipped probe warnings at shutdown.
Diffstat (limited to 'translate.cxx')
-rw-r--r-- | translate.cxx | 47 |
1 files changed, 34 insertions, 13 deletions
diff --git a/translate.cxx b/translate.cxx index bda28e8b..78788de9 100644 --- a/translate.cxx +++ b/translate.cxx @@ -1,5 +1,5 @@ // translation pass -// Copyright (C) 2005 Red Hat Inc. +// Copyright (C) 2005, 2006 Red Hat Inc. // Copyright (C) 2005 Intel Corporation // // This file is part of systemtap, and is free software. You can @@ -444,11 +444,10 @@ struct varlock c.o->newline() << "{"; c.o->newline(1) << "unsigned trylock_count = 0;"; c.o->newline() << "while (" - << "!(write_trylock (& " << v << "_lock))" - << " && " - << "(trylock_count++ < MAXTRYLOCK)" - << ") ; /* spin */"; - c.o->newline() << "if (unlikely (trylock_count >= MAXTRYLOCK)) {"; + << "!(write_trylock (& " << v << "_lock)) &&"; + c.o->newline(1) << "(trylock_count++ < MAXTRYLOCK)" + << ") ndelay (TRYLOCKDELAY); /* spin */"; + c.o->newline(-1) << "if (unlikely (trylock_count >= MAXTRYLOCK)) {"; c.o->newline(1) << "c->last_error = \"locking timeout over variable " << v << "\";"; c.o->newline() << "goto " << post_unlock_label << ";"; @@ -820,6 +819,8 @@ c_unparser::emit_common_header () o->newline() << "#define STAP_SESSION_STOPPING 3"; o->newline() << "#define STAP_SESSION_STOPPED 4"; o->newline() << "atomic_t session_state = ATOMIC_INIT (STAP_SESSION_STARTING);"; + o->newline() << "atomic_t error_count = ATOMIC_INIT (0);"; + o->newline() << "atomic_t skipped_count = ATOMIC_INIT (0);"; o->newline(); o->newline() << "struct context {"; o->newline(1) << "atomic_t busy;"; @@ -942,7 +943,7 @@ void c_unparser::emit_functionsig (functiondecl* v) { o->newline() << "static void function_" << v->name - << " (struct context *c);"; + << " (struct context * __restrict__ c);"; } @@ -1101,6 +1102,15 @@ c_unparser::emit_module_exit () o->newline() << "free_percpu (contexts);"; + // print final error/reentrancy counts if non-zero + o->newline() << "if (atomic_read (& skipped_count) || " + << "atomic_read (& error_count))"; + o->newline(1) << "_stp_warn (\"Number of errors: %d, " + << "skipped probes: %d\\n\", " + << "(int) atomic_read (& error_count), " + << "(int) atomic_read (& skipped_count));"; + o->indent(-1); + o->newline(-1) << "}" << endl; } @@ -1109,7 +1119,7 @@ void c_unparser::emit_function (functiondecl* v) { o->newline() << "void function_" << c_varname (v->name) - << " (struct context* c) {"; + << " (struct context* __restrict__ c) {"; o->indent(1); this->current_probe = 0; this->current_probenum = 0; @@ -1160,8 +1170,8 @@ c_unparser::emit_function (functiondecl* v) void c_unparser::emit_probe (derived_probe* v, unsigned i) { - o->newline() << "static void probe_" << i << " (struct context *c);"; - o->newline() << "void probe_" << i << " (struct context *c) {"; + // o->newline() << "static void probe_" << i << " (struct context *c);"; + o->newline() << "static void probe_" << i << " (struct context * __restrict__ c) {"; o->indent(1); // initialize frame pointer @@ -1667,6 +1677,7 @@ c_unparser::visit_statement (statement *s, unsigned actions) if (actions > 0) { o->newline() << "c->actioncount += " << actions << ";"; + // XXX: This check is inserted too frequently. o->newline() << "if (unlikely (c->actioncount > MAXACTION)) {"; o->newline(1) << "c->last_error = \"MAXACTION exceeded\";"; o->newline() << "goto " << outlabel << ";"; @@ -3437,15 +3448,24 @@ translate_pass (systemtap_session& s) s.op->newline() << "#ifndef MAXSTRINGLEN"; s.op->newline() << "#define MAXSTRINGLEN 128"; s.op->newline() << "#endif"; - s.op->newline() << "#ifndef MAXTRYLOCK"; - s.op->newline() << "#define MAXTRYLOCK 20"; - s.op->newline() << "#endif"; s.op->newline() << "#ifndef MAXACTION"; s.op->newline() << "#define MAXACTION 1000"; s.op->newline() << "#endif"; + s.op->newline() << "#ifndef MAXTRYLOCK"; + s.op->newline() << "#define MAXTRYLOCK MAXACTION"; + s.op->newline() << "#endif"; + s.op->newline() << "#ifndef TRYLOCKDELAY"; + s.op->newline() << "#define TRYLOCKDELAY 100"; + s.op->newline() << "#endif"; s.op->newline() << "#ifndef MAXMAPENTRIES"; s.op->newline() << "#define MAXMAPENTRIES 2048"; s.op->newline() << "#endif"; + s.op->newline() << "#ifndef MAXERRORS"; + s.op->newline() << "#define MAXERRORS 10"; + s.op->newline() << "#endif"; + s.op->newline() << "#ifndef MAXSKIPPED"; + s.op->newline() << "#define MAXSKIPPED 100"; + s.op->newline() << "#endif"; // impedance mismatch s.op->newline() << "#define STP_STRING_SIZE MAXSTRINGLEN"; @@ -3463,6 +3483,7 @@ translate_pass (systemtap_session& s) s.op->newline() << "#include \"regs.c\""; s.op->newline() << "#include <linux/string.h>"; s.op->newline() << "#include <linux/timer.h>"; + s.op->newline() << "#include <linux/delay.h>"; s.op->newline() << "#include <linux/profile.h>"; s.op->newline() << "#endif"; s.op->newline() << "#include \"loc2c-runtime.h\" "; |