diff options
author | Josh Stone <jistone@redhat.com> | 2009-10-21 16:15:58 -0700 |
---|---|---|
committer | Josh Stone <jistone@redhat.com> | 2009-10-21 16:36:25 -0700 |
commit | 29bb0bbc8603edb20de09e79fd8addb4a174947d (patch) | |
tree | 2d39d41b9479c87839e22b9a9c81a4830d315377 /runtime/probe_lock.h | |
parent | 1d2cd5ff6a8ff79b09e342a5907b29b4c340a9a5 (diff) | |
download | systemtap-steved-29bb0bbc8603edb20de09e79fd8addb4a174947d.tar.gz systemtap-steved-29bb0bbc8603edb20de09e79fd8addb4a174947d.tar.xz systemtap-steved-29bb0bbc8603edb20de09e79fd8addb4a174947d.zip |
Refactor probe locking into shared functions
For scripts with thousands of probes, we save a fair amount of code-gen
time in pass-4 by having the common locking code extracted into shared
functions.
* runtime/probe_lock.h (stp_lock_probe, stp_unlock_probe): New.
* translate.cxx (c_unparser::emit_lock_decls): New, emits a static
const array of locks needed for each probe.
(c_unparser::emit_locks): Just call stp_lock_probe.
(c_unparser::emit_unlocks): Just call stp_unlock_probe.
Diffstat (limited to 'runtime/probe_lock.h')
-rw-r--r-- | runtime/probe_lock.h | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/runtime/probe_lock.h b/runtime/probe_lock.h new file mode 100644 index 00000000..1915d4ff --- /dev/null +++ b/runtime/probe_lock.h @@ -0,0 +1,68 @@ +/* probe locking header file + * Copyright (C) 2009 Red Hat Inc. + * + * This file is part of systemtap, and is free software. You can + * redistribute it and/or modify it under the terms of the GNU General + * Public License (GPL); either version 2, or (at your option) any + * later version. + */ + +#ifndef _PROBE_LOCK_H +#define _PROBE_LOCK_H + +#include <linux/spinlock.h> + +// XXX: old 2.6 kernel hack +#ifndef read_trylock +#define read_trylock(x) ({ read_lock(x); 1; }) +#endif + +struct stp_probe_lock { + #ifdef STP_TIMING + atomic_t *skipped; + #endif + rwlock_t *lock; + unsigned write_p; +}; + + +static void +stp_unlock_probe(const struct stp_probe_lock *locks, unsigned num_locks) +{ + unsigned i; + for (i = num_locks; i-- > 0;) { + if (locks[i].write_p) + write_unlock(locks[i].lock); + else + read_unlock(locks[i].lock); + } +} + + +static unsigned +stp_lock_probe(const struct stp_probe_lock *locks, unsigned num_locks) +{ + unsigned i, numtrylock = 0; + for (i = 0; i < num_locks; ++i) { + if (locks[i].write_p) + while (!write_trylock(locks[i].lock) && + (++numtrylock < MAXTRYLOCK)) + ndelay (TRYLOCKDELAY); + else + while (!read_trylock(locks[i].lock) && + (++numtrylock < MAXTRYLOCK)) + 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; +} + + +#endif /* _PROBE_LOCK_H */ |