xentrace_format

来源:互联网 发布:淘宝交了定金可以退吗 编辑:程序博客网 时间:2024/04/30 13:59

#!/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) < 2:

    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 < 0:

                break

            irq_measure[d1]['count'] += 1

            irq_measure[d1]['tot_cycles'] += tsc_diff

            if irq_measure[d1]['max_cycles'] < tsc_diff:

                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<<32) | tscL

 

        #print i, tsc

 

        if cpu >= len(last_tsc):

            last_tsc += [0] * (cpu - len(last_tsc) + 1)

        elif tsc < last_tsc[cpu] and tsc_in == 1:

            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;

};


原创粉丝点击