Sophie

Sophie

distrib > Mageia > 1 > i586 > media > core-updates > by-pkgid > fe7c341633b7d979ab8178b22304d6b5 > files > 196

systemtap-1.3-1.1.mga1.i586.rpm

#! /usr/bin/env stap

# Record the time that a process has spent asleep, and in what function

global enqueued
global sleep_time
global process_names
global sleep_agg

function _get_sleep_time:long(rq_param:long, p_param:long) %{ /* pure */
        struct rq *rq = (struct rq *)(unsigned long)THIS->rq_param;
        struct task_struct *p = (struct task_struct *)(unsigned long)THIS->p_param;
        struct sched_entity *se = &p->se;
        u64 delta = cpu_clock(smp_processor_id()) - se->sleep_start;

        if ((s64)delta < 0)
                delta = 0;
        THIS->__retvalue = delta;
%}

# Get the backtrace from an arbitrary task
function task_backtrace:string (task:long) %{ /* pure */
    _stp_stack_snprint_tsk(THIS->__retvalue, MAXSTRINGLEN,
                           (struct task_struct *)(unsigned long)THIS->task, 0, MAXTRACE);
%}

probe kernel.function("enqueue_task_fair") {
    if ($wakeup == 1) {
        this_sleep = _get_sleep_time($rq, $p)
        if (this_sleep > 0) {
            sleep_time[$p->pid, task_backtrace($p)] += this_sleep
            sleep_agg[$p->pid] <<< this_sleep
            process_names[$p->pid] = kernel_string($p->comm)
        }
    }
}

global pid_sleep
probe timer.ms(1000) {
    foreach ([pid, backtrace] in sleep_time) {
        pid_sleep[pid] += sleep_time[pid, backtrace]
        printf("%s %d:\n", process_names[pid], pid)
        print_stack(backtrace)
        printf("\n")
    }
    foreach ([pid+] in pid_sleep) {
        printf("%s %d %d\n", process_names[pid], @max(sleep_agg[pid]) / 1000000, @avg(sleep_agg[pid]) / 1000000) 
    }
    # decode backtraces; unfortunately they are empty at the moment.
    delete pid_sleep
    delete sleep_time
    delete process_names
}