diff options
author | Josh Stone <jistone@redhat.com> | 2010-03-11 17:14:59 -0800 |
---|---|---|
committer | Josh Stone <jistone@redhat.com> | 2010-03-11 17:15:20 -0800 |
commit | 0da46fcdec144f944838350f08f59a36b8709e90 (patch) | |
tree | 8b825a01177517b50af0da37a1f422ac5a34e96e /runtime | |
parent | 40e400d07bcfa621eef5b4f4496b7af665089e55 (diff) | |
download | systemtap-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.
Diffstat (limited to 'runtime')
-rw-r--r-- | runtime/probe_lock.h | 30 |
1 files changed, 17 insertions, 13 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; } |