/************************************************************************** * * * Copyright (c) International Business Machines Corp., 2005 * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, but * * WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * * * Author: Guanglei Li (guanglei@cn.ibm.com) * **************************************************************************/ /* Log the data common to all events */ function log_tracedata_common(hookID:long) %{ struct timeval tv; struct task_struct *cur = current; /* second|usec|pid|ppid|tid|cpuid|hoodID */ do_gettimeofday (&tv); /* The actual format is a TBD. we currently print the ascii string for convenience. */ _stp_printf("\n%ld|%ld|%ld|%ld|%ld|%u|%ld|", tv.tv_sec, tv.tv_usec, cur->tgid, cur->parent->pid, cur->pid, cur->thread_info->cpu,THIS->hookID); %} /* Log the data defined by users */ function log_user_data(input:string) %{ struct task_struct *cur = current; if(cur->tgid != _stp_pid) { if( _stp_target != 0 && cur->tgid != _stp_target) return; /* here USER: is a seperator. we use this for convenience. It may be changed in future. */ _stp_printf ("USER:%s|", THIS->input); } %} /****************************************************************** * a demo for data compress, a substitute for log_tracedata_common * * If a field of a row has the same value as the same field in the * * previous row, it will be replaces by *. I omit cpuid and eventid* * because they are already one-byte. * * * * The following two functions haven't been used. We need some * * overhead testing and more work to find a better solution. * ******************************************************************/ function log_tracedata_common_compact(hookID:long) %{ static time_t old_second; static pid_t old_pid, old_ppid, old_tgid; char buffer[128]; int len; struct timeval tv; struct task_struct *cur = current; len = 0; /* second|usec|pid|ppid|tid|cpu|hoodID */ do_gettimeofday (&tv); buffer[len++] = '\n'; if(tv.tv_sec != old_second) len += sprintf(buffer+len, "%d|", (int)tv.tv_sec); else { buffer[len++] = '*'; buffer[len++] = '|'; } len += sprintf(buffer+len, "%d|", (int)tv.tv_usec); if( cur->tgid != old_tgid) len += sprintf(buffer+len, "%d|", (int)cur->tgid); else { buffer[len++] = '*'; buffer[len++] = '|'; } if( cur->parent->pid != old_ppid) len += sprintf(buffer+len, "%d|", (int)cur->parent->pid); else { buffer[len++] = '*'; buffer[len++] = '|'; } if( cur->pid != old_pid) len += sprintf(buffer+len, "%d|", (int)cur->pid); else { buffer[len++] = '*'; buffer[len++] = '|'; } len += sprintf(buffer+len, "%u|%d|", (int)cur->thread_info->cpu,(int)THIS->hookID); buffer[len]='\0'; _stp_print_cstr(buffer); old_second = tv.tv_sec; old_pid = cur->pid; old_ppid = cur->parent->pid; old_tgid = cur->tgid; %} /******************************************************************* * a demo for data compress, will further compress the data got from* * log_tracedata_common_compact. If there are consecutive asterisk * * in a row outputed by log_tracedata_common_compact(), they will be* * replaced with *number. * ******************************************************************/ function log_tracedata_common_compact_more(hookID:long) %{ static time_t old_second; static pid_t old_pid, old_ppid, old_tgid; char buffer[128]; int len; int counter; struct timeval tv; struct task_struct *cur = current; len = 0; counter=0; /* second|usec|pid|ppid|tgid|cpuid|hoodID */ do_gettimeofday (&tv); buffer[len++] = '\n'; if(tv.tv_sec != old_second) len += sprintf(buffer+len, "%d|", (int)tv.tv_sec); else { buffer[len++] = '*'; buffer[len++] = '|'; } len += sprintf(buffer+len, "%d|", (int)tv.tv_usec); if( cur->tgid != old_tgid) len += sprintf(buffer+len, "%d|", (int)cur->tgid); else counter++; if( cur->parent->pid != old_ppid) { len += sprintf(buffer+len, "%d|", (int)cur->parent->pid); if(counter > 0) { len += sprintf(buffer+len, "*%d|", counter); counter=0; } } else counter++; if( cur->pid != old_pid) { len += sprintf(buffer+len, "%d|", (int)cur->pid); if(counter > 0) { len += sprintf(buffer+len, "*%d|", counter); counter=0; } } else counter++; if(counter > 0) { len += sprintf(buffer+len, "*%d|", counter); counter=0; } len += sprintf(buffer+len, "%u|%d|", (int)cur->thread_info->cpu,(int)THIS->hookID); buffer[len]='\0'; _stp_print_cstr(buffer); old_second = tv.tv_sec; old_pid = cur->pid; old_ppid = cur->parent->pid; old_tgid = cur->tgid; %}