summaryrefslogtreecommitdiffstats
path: root/tapsets.cxx
diff options
context:
space:
mode:
authorfche <fche>2006-04-17 20:32:18 +0000
committerfche <fche>2006-04-17 20:32:18 +0000
commit4a5e8a70d3263060375fee5e98ab9c2f386ae9c2 (patch)
treea7e1091e8b89a0289dfc7548ed1f67685de4cb22 /tapsets.cxx
parenta419971a4865c7abf0d05ed61abad74d5e66dc2d (diff)
downloadsystemtap-steved-4a5e8a70d3263060375fee5e98ab9c2f386ae9c2.tar.gz
systemtap-steved-4a5e8a70d3263060375fee5e98ab9c2f386ae9c2.tar.xz
systemtap-steved-4a5e8a70d3263060375fee5e98ab9c2f386ae9c2.zip
2006-04-17 Frank Ch. Eigler <fche@elastic.org>
* tapsets.cxx (mark_derived_probe::emit_{de}registrations): Use cmpxchg to synchronize.
Diffstat (limited to 'tapsets.cxx')
-rw-r--r--tapsets.cxx14
1 files changed, 14 insertions, 0 deletions
diff --git a/tapsets.cxx b/tapsets.cxx
index 12982259..5390ee2d 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -3506,8 +3506,15 @@ mark_derived_probe::emit_registrations (translator_output * o, unsigned i)
o->newline(1) << "void (**fn) (" << probe_sig_expanded << ") = (void *)"
<< address << "UL;";
+ o->newline() << "#if __HAVE_ARCH_CMPXCHG";
+ o->newline() << "unsigned long *fnpp = (unsigned long *) (void *) fn;";
+ o->newline() << "unsigned long fnp = (unsigned long) (void *) & enter_" << i << ";";
+ o->newline() << "unsigned long oldval = cmpxchg (fnpp, 0, fnp);";
+ o->newline() << "if (oldval != 0) rc = 1;"; // XXX: could retry a few times
+ o->newline() << "#else";
// XXX: need proper synchronization for concurrent registration attempts
o->newline() << "if (*fn == 0) *fn = & enter_" << i << ";";
+ o->newline() << "#endif";
o->newline() << "mb ();";
o->newline() << "if (*fn != & enter_" << i << ") rc = 1;";
@@ -3523,7 +3530,14 @@ mark_derived_probe::emit_deregistrations (translator_output * o, unsigned i)
o->newline() << "{";
o->newline(1) << "void (**fn) (" << probe_sig_expanded << ") = (void *)"
<< address << "UL;";
+ o->newline() << "#if __HAVE_ARCH_CMPXCHG";
+ o->newline() << "unsigned long *fnpp = (unsigned long *) (void *) fn;";
+ o->newline() << "unsigned long fnp = (unsigned long) (void *) & enter_" << i << ";";
+ o->newline() << "unsigned long oldval = cmpxchg (fnpp, fnp, 0);";
+ o->newline() << "if (oldval != fnp) ;"; // XXX: should not happen
+ o->newline() << "#else";
o->newline(0) << "*fn = 0;";
+ o->newline() << "#endif";
o->newline(-1) << "}";
}