免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1197 | 回复: 0
打印 上一主题 下一主题

xentrace_format [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-02-03 09:54 |只看该作者 |倒序浏览
#!/usr/bin/env python

# by Mark Williamson, (C) 2004 Intel Research Cambridge

# Program for reformatting trace buffer output according to user-supplied rules

import re, sys, string, signal, struct, os, getopt

def usage():
    print >> sys.stderr, \
          "Usage: " + sys.argv[0] + """ defs-file
          Parses trace data in binary format, as output by Xentrace and
          reformats it according to the rules in a file of definitions.  The
          rules in this file should have the format ({ and } show grouping
          and are not part of the syntax):

          {event_id}{whitespace}{text format string}

          The textual format string may include format specifiers, such as:
            %(cpu)d, %(tsc)d, %(event)d, %(1)d, %(2)d, %(3)d, %(4)d, ...
          [ the 'd' format specifier outputs in decimal, alternatively 'x'
            will output in hexadecimal and 'o' will output in octal ]

          Which correspond to the CPU number, event ID, timestamp counter and
          the 7 data fields from the trace record.  There should be one such
          rule for each type of event.
         
          Depending on your system and the volume of trace buffer data,
          this script may not be able to keep up with the output of xentrace
          if it is piped directly.  In these circumstances you should have
          xentrace output to a file for processing off-line.
          """
    sys.exit(1)

def read_defs(defs_file):
    defs = {}
   
    fd = open(defs_file)

    reg = re.compile('(\S+)\s+(\S.*)')     // 对正则表达式的处理使用re模块

    while True:
        line = fd.readline()
        if not line:
            break

        if line[0] == '#' or line[0] == '\n':
            continue

        m = reg.match(line)

        if not m: print >> sys.stderr, "Bad format file" ; sys.exit(1)

        defs[str(eval(m.group(1)))] = m.group(2)    // 以EVENTID的十进制做key

    return defs

def sighand(x,y):
    global interrupted
    interrupted = 1

##### Main code

mhz = 0

if len(sys.argv)
    usage()

try:
    opts, arg = getopt.getopt(sys.argv[1:], "c:" )

    for opt in opts:                     // 获得的options信息存放到opts
        if opt[0] == '-c' : mhz = int(opt[1])

except getopt.GetoptError:                          // getopt.getopt需要处理getopt.GetoptError异常
    usage()

signal.signal(signal.SIGTERM, sighand)
signal.signal(signal.SIGHUP,  sighand)
signal.signal(signal.SIGINT,  sighand)

interrupted = 0

try:
    defs =
read_defs
(arg[0])    // arg数组为剩余命令行参数列表
except IOError, exn:
    print exn
    sys.exit(1)

# structure of trace record (as output by xentrace):
# HDR(I) {TSC(Q)} D1(I) D2(I) D3(I) D4(I) D5(I) D6(I) D7(I)
#
# HDR consists of EVENT:28:, n_data:3:, tsc_in:1:                    // 参考struct
t_rec
# EVENT means Event ID
# n_data means number of data (like D1, D2, ...)
# tsc_in means TSC data exists(1) or not(0).
# if tsc_in == 0, TSC(Q) does not exists.
#
# CPU ID exists on trace data of EVENT=0x0001f003
#
HDRREC = "I"                             // ui
TSCREC = "Q"                            // ull
D1REC  = "I"
D2REC  = "II"
D3REC  = "III"
D4REC  = "IIII"
D5REC  = "IIIII"
D6REC  = "IIIIII"
D7REC  = "IIIIIII"

last_tsc = [0]

TRC_TRACE_IRQ = 0x1f004
NR_VECTORS = 256
irq_measure = [{'count':0, 'tot_cycles':0, 'max_cycles':0}] * NR_VECTORS

i=0

while not interrupted:                // 如果没有信号打断
    try:
        i=i+1
        line = sys.stdin.read(struct.calcsize(HDRREC))         // 读入4个字节
        if not line:
            break
        event = struct.unpack(HDRREC, line)[0]                      // 将字节流转换为python数据类型
        n_data = event >> 28 & 0x7                                             // 数据个数
        tsc_in = event >> 31                                                           // 时间戳flag

        d1 = 0
        d2 = 0
        d3 = 0
        d4 = 0
        d5 = 0
        d6 = 0
        d7 = 0

        tsc = 0

        if tsc_in == 1:
            line = sys.stdin.read(struct.calcsize(TSCREC))
            if not line:
                break
            tsc = struct.unpack(TSCREC, line)[0]

        if n_data == 1:
            line = sys.stdin.read(struct.calcsize(D1REC))
            if not line:
                break
            d1 = struct.unpack(D1REC, line)[0]
        if n_data == 2:
            line = sys.stdin.read(struct.calcsize(D2REC))
            if not line:
                break
            (d1, d2) = struct.unpack(D2REC, line)
        if n_data == 3:
            line = sys.stdin.read(struct.calcsize(D3REC))
            if not line:
                break
            (d1, d2, d3) = struct.unpack(D3REC, line)
        if n_data == 4:
            line = sys.stdin.read(struct.calcsize(D4REC))
            if not line:
                break
            (d1, d2, d3, d4) = struct.unpack(D4REC, line)
        if n_data == 5:
            line = sys.stdin.read(struct.calcsize(D5REC))
            if not line:
                break
            (d1, d2, d3, d4, d5) = struct.unpack(D5REC, line)
        if n_data == 6:
            line = sys.stdin.read(struct.calcsize(D6REC))
            if not line:
                break
            (d1, d2, d3, d4, d5, d6) = struct.unpack(D6REC, line)
        if n_data == 7:
            line = sys.stdin.read(struct.calcsize(D7REC))
            if not line:
                break
            (d1, d2, d3, d4, d5, d6, d7) = struct.unpack(D7REC, line)

        # Event field is 28bit of 'uint32_t' in header, not 'long'.
        event &= 0x0fffffff
        if event == 0x1f003:                      // TRC_TRACE_CPU_CHANGE
            cpu = d1

        if event == TRC_TRACE_IRQ:
            # IN - d1:vector, d2:tsc_in, d3:tsc_out
            # OUT - d1:vector, d2:count, d3:tot_cycles, d4:max_cycles
            tsc_diff = d3 - d2
            if tsc_diff
                break
            irq_measure[d1]['count'] += 1
            irq_measure[d1]['tot_cycles'] += tsc_diff
            if irq_measure[d1]['max_cycles']
                irq_measure[d1]['max_cycles'] = tsc_diff
            d2 = irq_measure[d1]['count']
            d3 = irq_measure[d1]['tot_cycles']
            d4 = irq_measure[d1]['max_cycles']

        #tsc = (tscH

        #print i, tsc

        if cpu >= len(last_tsc):
            last_tsc += [0] * (cpu - len(last_tsc) + 1)
        elif tsc
            print "TSC stepped backward cpu %d !  %d %d" % (cpu,tsc,last_tsc[cpu])

        # provide relative TSC
        if last_tsc[cpu] > 0 and tsc_in == 1:
            reltsc = tsc - last_tsc[cpu]
        else:
            reltsc = 0

        if tsc_in == 1:
            last_tsc[cpu] = tsc

        if mhz:
            tsc = tsc / (mhz*1000000.0)

        args = {'cpu'   : cpu,
                'tsc'   : tsc,
                'event' : event,
                'reltsc': reltsc,
                '1'     : d1,
                '2'     : d2,
                '3'     : d3,
                '4'     : d4,
                '5'     : d5,
                '6'     : d6,
                '7'     : d7    }

        try:

            if defs.has_key(str(event)):
                print defs[str(event)] % args
-------------------------------------------------------------------------------------------------------------------------------------
defs中得到此EVENTID对应的格式化字符串,例print  "CPU%(cpu)d %(tsc)d %(1)d" % args
所以,输出格式文件中的每一行,实际是python对散列表里的元素进行输出时,采用的一种格式
-------------------------------------------------------------------------------------------------------------------------------------
            else:
                if defs.has_key(str(0)): print defs[str(0)] % args
        except TypeError:
            if defs.has_key(str(event)):
                print defs[str(event)]
                print args
            else:
                if defs.has_key(str(0)):
                    print defs[str(0)]
                    print args


    except IOError, struct.error: sys.exit()

/* This structure represents a single trace buffer record. */
struct t_rec {
    uint32_t event:28;
    uint32_t extra_u32:3;         /* # entries in trailing extra_u32[] array */
    uint32_t cycles_included:1;   /* u.cycles or u.no_cycles? */
    union {
        struct {
            uint32_t cycles_lo, cycles_hi; /* cycle counter timestamp */
            uint32_t extra_u32[7];         /* event data items */
        } cycles;
        struct {
            uint32_t extra_u32[7];         /* event data items */
        } nocycles;
    } u;
};


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u3/110937/showart_2169591.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP