This is the mail archive of the
systemtap@sourceware.org
mailing list for the systemtap project.
Re: systemtap application to find applications doing polling
- From: Jim Keniston <jkenisto at us dot ibm dot com>
- To: William Cohen <wcohen at redhat dot com>
- Cc: SystemTAP <systemtap at sources dot redhat dot com>, Ulrich Drepper <drepper at redhat dot com>
- Date: Wed, 28 Jan 2009 12:19:54 -0800
- Subject: Re: systemtap application to find applications doing polling
- References: <49808D3A.7070905@redhat.com>
On Wed, 2009-01-28 at 11:52 -0500, William Cohen wrote:
> Hi All,
>
> Uli Drepper mentions in a blog entry need "avoid unnecessary wakeups" and that a
> systemtap script to monitor this would be useful:
...
>
> I plan to check this into systemtap.examples directory in next day or so. Just
> looking to see if people have additional suggestions.
>
> -Will
> # Copyright (C) 2009 Red Hat, Inc.
> # Written by Ulrich Drepper <drepper@redhat.com>
> # Modified by William Cohen <wcohen@redhat.com>
>
> global process, timeout_count, to
> global poll_timeout, epoll_timeout, select_timeout, itimer_timeout
> global nanosleep_timeout, futex_timeout, signal_timeout
>
> probe syscall.poll, syscall.epoll_wait {
> if (timeout) to[pid()]=timeout
> }
>
> probe syscall.poll.return {
> p = pid()
> if ($return == 0 && to[p] > 0 ) {
> poll_timeout[p]++
> timeout_count[p]++
> process[p] = execname()
> delete to[p]
> }
> }
I'm wondering if this script could be shorter (though perhaps less
efficient) if you used a function like this:
global timeouts
function tally_timeout(name:string) {
p = pid()
timeouts[name, p]++
timeout_count[p]++
process[p] = execname()
}
>
> probe syscall.epoll_wait.return {
> if ($return == 0 && to[p] > 0 ) {
Here p is used before it is set.
> p = pid()
> epoll_timeout[p]++
> timeout_count[p]++
> process[p] = execname()
> delete to[p]
> }
> }
The above could turn into
p = pid()
if ($return == 0 && to[p] > 0) {
tally_timeout(name)
delete to[p]
}
>
> probe syscall.select.return {
> if ($return == 0) {
> p = pid()
> select_timeout[p]++
> timeout_count[p]++
> process[p] = execname()
> }
> }
>
> probe syscall.futex.return {
> if (errno_str($return) == "ETIMEDOUT") {
> p = pid()
> futex_timeout[p]++
> timeout_count[p]++
> process[p] = execname()
> }
> }
>
> probe syscall.nanosleep.return {
> if ($return == 0) {
> p = pid()
> nanosleep_timeout[p]++
> timeout_count[p]++
> process[p] = execname()
> }
> }
>
> probe kernel.function("it_real_fn") {
> p = pid()
> itimer_timeout[p]++
> timeout_count[p]++
> process[p] = execname()
> }
>
> probe syscall.rt_sigtimedwait.return {
> if (errno_str($return) == "EAGAIN") {
> p = pid()
> signal_timeout[p]++
> timeout_count[p]++
> process[p] = execname()
> }
> }
>
> probe syscall.exit {
> p = pid()
> if (p in process) {
> delete process[p]
> delete timeout_count[p]
> delete poll_timeout[p]
> delete epoll_timeout[p]
> delete select_timeout[p]
> delete itimer_timeout[p]
> delete futex_timeout[p]
> delete nanosleep_timeout[p]
> delete signal_timeout[p]
> }
> }
>
> probe timer.s(1) {
> printf("\033[2J\033[1;1H") /* clear screen */
> printf (" uid | poll select epoll itimer futex nanosle signal| process\n")
> foreach (p in timeout_count- limit 20) {
> printf ("%5d |%7d %7d %7d %7d %7d %7d %7d| %-.38s\n", p,
> poll_timeout[p], select_timeout[p],
> epoll_timeout[p], itimer_timeout[p],
> futex_timeout[p], nanosleep_timeout[p],
> signal_timeout[p], process[p])
> }
> }
Jim