summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosh Stone <jistone@redhat.com>2010-03-11 17:14:59 -0800
committerJosh Stone <jistone@redhat.com>2010-03-11 17:15:20 -0800
commit0da46fcdec144f944838350f08f59a36b8709e90 (patch)
tree8b825a01177517b50af0da37a1f422ac5a34e96e
parent40e400d07bcfa621eef5b4f4496b7af665089e55 (diff)
downloadsystemtap-steved-0da46fcdec144f944838350f08f59a36b8709e90.tar.gz
systemtap-steved-0da46fcdec144f944838350f08f59a36b8709e90.tar.xz
systemtap-steved-0da46fcdec144f944838350f08f59a36b8709e90.zip
Fix the edge-case of MAXTRYLOCK=0
We didn't really have good semantics for what is meant by MAXTRYLOCK=0, so when skipped.exp tried it, we ended up locking the variable and then reporting a skip without ever unlocking it. This is now cleaning up the semantics such that MAXTRYLOCK defines how many times we should loop if the lock is busy. Thus MAXTRYLOCK=0 means we try only once and fail immediately. The testcase was accidentally creating contention due to the broken unlock behavior. We now have to try a bit harder to create real contention, so some lengthy delays are inserted to hoard the lock. * runtime/probe_lock.h (stp_probe_lock): Fix the skip behavior. * testsuite/systemtap.base/skipped.exp: Add a big udelay.
-rw-r--r--runtime/probe_lock.h30
-rw-r--r--testsuite/systemtap.base/skipped.exp8
2 files changed, 24 insertions, 14 deletions
diff --git a/runtime/probe_lock.h b/runtime/probe_lock.h
index 1915d4ff..1077f4c6 100644
--- a/runtime/probe_lock.h
+++ b/runtime/probe_lock.h
@@ -42,26 +42,30 @@ stp_unlock_probe(const struct stp_probe_lock *locks, unsigned num_locks)
static unsigned
stp_lock_probe(const struct stp_probe_lock *locks, unsigned num_locks)
{
- unsigned i, numtrylock = 0;
+ unsigned i, retries = 0;
for (i = 0; i < num_locks; ++i) {
if (locks[i].write_p)
- while (!write_trylock(locks[i].lock) &&
- (++numtrylock < MAXTRYLOCK))
+ while (!write_trylock(locks[i].lock)) {
+ if (++retries > MAXTRYLOCK)
+ goto skip;
ndelay (TRYLOCKDELAY);
+ }
else
- while (!read_trylock(locks[i].lock) &&
- (++numtrylock < MAXTRYLOCK))
+ while (!read_trylock(locks[i].lock)) {
+ if (++retries > MAXTRYLOCK)
+ goto skip;
ndelay (TRYLOCKDELAY);
- if (unlikely(numtrylock >= MAXTRYLOCK)) {
- atomic_inc(&skipped_count);
- #ifdef STP_TIMING
- atomic_inc(locks[i].skipped);
- #endif
- stp_unlock_probe(locks, i);
- return 0;
- }
+ }
}
return 1;
+
+skip:
+ atomic_inc(&skipped_count);
+#ifdef STP_TIMING
+ atomic_inc(locks[i].skipped);
+#endif
+ stp_unlock_probe(locks, i);
+ return 0;
}
diff --git a/testsuite/systemtap.base/skipped.exp b/testsuite/systemtap.base/skipped.exp
index 8815c737..f12bc6f1 100644
--- a/testsuite/systemtap.base/skipped.exp
+++ b/testsuite/systemtap.base/skipped.exp
@@ -5,10 +5,16 @@ if {! [installtest_p]} { untested $test; return }
set nr_cpus [exec sh -c "grep ^processor /proc/cpuinfo | wc -l"]
if {$nr_cpus < 2} { unsupported $test; return }
+set script {
+global f
+probe timer.profile { f++; snooze() }
+function snooze() %{ udelay(10000); %}
+}
+
set errs 0
set warns 0
set oks 0
-spawn stap -e "probe timer.s(5) {exit()} probe timer.profile,syscall.* {f++} global f" -DMAXTRYLOCK=0 -tu
+spawn stap -e $script -DMAXTRYLOCK=0 -DSTP_NO_OVERLOAD -tug
expect {
-timeout 60
-re {^ERROR: Skipped too many probes, check MAXSKIPPED or try again with stap -t for more details.\r\n} { incr errs; exp_continue }