diff options
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | translate.cxx | 40 |
2 files changed, 45 insertions, 4 deletions
@@ -1,5 +1,14 @@ 2007-03-30 David Smith <dsmith@redhat.com> + PR 2341 + * translate.cxx (c_unparser::emit_locks): No longer emits a read + lock for global variables that are only written to in begin/end + probes. + (c_unparser::emit_unlocks): Ditto. + (translate_pass): Runs a varuse_collecting_visitor over probes + that need global variable locks for use in + emit_locks()/emit_unlocks(). + * stap.1.in: Corrected probe overload processing text. 2007-03-29 David Smith <dsmith@redhat.com> diff --git a/translate.cxx b/translate.cxx index 73646c85..6dc72fef 100644 --- a/translate.cxx +++ b/translate.cxx @@ -39,6 +39,8 @@ struct c_unparser: public unparser, public visitor unsigned tmpvar_counter; unsigned label_counter; + varuse_collecting_visitor vcv_needs_global_locks; + map<string, string> probe_contents; c_unparser (systemtap_session* ss): @@ -1489,6 +1491,19 @@ c_unparser::emit_locks(const varuse_collecting_visitor& vut) else if (read_p && !write_p) { read_p = false; write_p = true; } } + // We don't need to read lock "read-mostly" global variables. A + // "read-mostly" global variable is only written to within + // probes that don't need global variable locking (such as + // begin/end probes). If vcv_needs_global_locks doesn't mark + // the global as written to, then we don't have to lock it + // here to read it safely. + if (read_p && !write_p) + { + if (vcv_needs_global_locks.written.find(v) + == vcv_needs_global_locks.written.end()) + continue; + } + string lockcall = string (write_p ? "write" : "read") + "_trylock (& global_" + v->name + "_lock)"; @@ -1528,10 +1543,6 @@ c_unparser::emit_unlocks(const varuse_collecting_visitor& vut) bool write_p = vut.written.find(v) != vut.written.end(); if (!read_p && !write_p) continue; - numvars ++; - o->newline(-1) << "unlock_" << v->name << ":"; - o->indent(1); - // Duplicate lock flipping logic from above if (v->type == pe_stats) { @@ -1539,6 +1550,18 @@ c_unparser::emit_unlocks(const varuse_collecting_visitor& vut) else if (read_p && !write_p) { read_p = false; write_p = true; } } + // Duplicate "read-mostly" global variable logic from above. + if (read_p && !write_p) + { + if (vcv_needs_global_locks.written.find(v) + == vcv_needs_global_locks.written.end()) + continue; + } + + numvars ++; + o->newline(-1) << "unlock_" << v->name << ":"; + o->indent(1); + if (session->verbose>1) clog << v->name << "[" << (read_p ? "r" : "") << (write_p ? "w" : "") << "] "; @@ -4170,6 +4193,15 @@ translate_pass (systemtap_session& s) s.up->emit_function (s.functions[i]); } + // Run a varuse_collecting_visitor over probes that need global + // variable locks. We'll use this information later in + // emit_locks()/emit_unlocks(). + for (unsigned i=0; i<s.probes.size(); i++) + { + if (s.probes[i]->needs_global_locks()) + s.probes[i]->body->visit (&cup.vcv_needs_global_locks); + } + for (unsigned i=0; i<s.probes.size(); i++) s.up->emit_probe (s.probes[i]); |