diff options
author | dsmith <dsmith> | 2007-03-30 16:01:57 +0000 |
---|---|---|
committer | dsmith <dsmith> | 2007-03-30 16:01:57 +0000 |
commit | 3be43eac84e5819b72dd311c3283ef2ea5bb1d83 (patch) | |
tree | 124db23eafac28fc4dadc5004b351c6356bdcf9e /translate.cxx | |
parent | de1814dcf92ac4045ca2e074ffa53bb48c014ad7 (diff) | |
download | systemtap-steved-3be43eac84e5819b72dd311c3283ef2ea5bb1d83.tar.gz systemtap-steved-3be43eac84e5819b72dd311c3283ef2ea5bb1d83.tar.xz systemtap-steved-3be43eac84e5819b72dd311c3283ef2ea5bb1d83.zip |
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().
Diffstat (limited to 'translate.cxx')
-rw-r--r-- | translate.cxx | 40 |
1 files changed, 36 insertions, 4 deletions
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]); |