summaryrefslogtreecommitdiffstats
path: root/translate.cxx
diff options
context:
space:
mode:
authordsmith <dsmith>2007-03-30 16:01:57 +0000
committerdsmith <dsmith>2007-03-30 16:01:57 +0000
commit3be43eac84e5819b72dd311c3283ef2ea5bb1d83 (patch)
tree124db23eafac28fc4dadc5004b351c6356bdcf9e /translate.cxx
parentde1814dcf92ac4045ca2e074ffa53bb48c014ad7 (diff)
downloadsystemtap-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.cxx40
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]);