summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--tapsets.cxx14
2 files changed, 19 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index 6a615670..acf5d88a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2006-04-17 Frank Ch. Eigler <fche@elastic.org>
+
+ * tapsets.cxx (mark_derived_probe::emit_{de}registrations):
+ Use cmpxchg to synchronize.
+
2006-04-12 Tom Zanussi <zanussi@us.ibm.com>
PR 2538
* buildrun.cxx (compile_pass): Remove space
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) << "}";
}