Source

pypy-stm-logging / pypy / tool / plot_log.py

Remi Meier 590a082 

Remi Meier 49b4586 


Remi Meier 590a082 
Remi Meier 0a26c1f 
Remi Meier ff3c660 
Remi Meier 9fe7595 
Remi Meier ff3c660 
Remi Meier 590a082 
Remi Meier bfeb8fb 




Remi Meier 0a26c1f 
Remi Meier a4eb7c5 

Remi Meier 0874e8e 
Remi Meier 590a082 
Remi Meier 9fe7595 





Remi Meier 9f5d327 
Remi Meier 9fe7595 
Remi Meier 590a082 
Remi Meier e272faf 






Remi Meier bfeb8fb 
Remi Meier e272faf 
Remi Meier bfeb8fb 

Remi Meier 590a082 
Remi Meier bfeb8fb 

Remi Meier 590a082 

Remi Meier bfeb8fb 
Remi Meier e272faf 
Remi Meier 590a082 
Remi Meier 49b4586 
Remi Meier 590a082 
Remi Meier 9fe7595 

Remi Meier 590a082 
Remi Meier 9fe7595 
Remi Meier 590a082 
Remi Meier 9fe7595 
Remi Meier 590a082 
Remi Meier e272faf 

Remi Meier 590a082 
Remi Meier bfeb8fb 
Remi Meier 590a082 
Remi Meier ff3c660 
Remi Meier bfeb8fb 
Remi Meier ff3c660 


Remi Meier 590a082 

Remi Meier 49b4586 
Remi Meier a4eb7c5 

Remi Meier 9fe7595 
Remi Meier e272faf 

Remi Meier 0874e8e 
Remi Meier e272faf 
Remi Meier 9f2a7ba 
Remi Meier bfeb8fb 



Remi Meier 0a26c1f 
Remi Meier bfeb8fb 
Remi Meier 590a082 
Remi Meier bfeb8fb 

Remi Meier 49b4586 
Remi Meier bfeb8fb 



Remi Meier 590a082 
Remi Meier bfeb8fb 


Remi Meier 9f2a7ba 
Remi Meier ff3c660 
Remi Meier e272faf 

Remi Meier bfeb8fb 


Remi Meier 590a082 
Remi Meier bfeb8fb 
Remi Meier ff3c660 
Remi Meier e272faf 

Remi Meier bfeb8fb 
Remi Meier e272faf 
Remi Meier ff3c660 
Remi Meier e272faf 
Remi Meier bfeb8fb 
Remi Meier a4eb7c5 
Remi Meier bfeb8fb 


Remi Meier b908712 

Remi Meier a4eb7c5 
Remi Meier 0874e8e 


Remi Meier ff3c660 
Remi Meier e272faf 
Remi Meier 0874e8e 
Remi Meier bfeb8fb 

Remi Meier 0874e8e 





Remi Meier a4eb7c5 
Remi Meier bfeb8fb 

Remi Meier b908712 

Remi Meier 0874e8e 
Remi Meier 9f2a7ba 
Remi Meier bfeb8fb 
Remi Meier 9f5d327 
Remi Meier 9f2a7ba 

Remi Meier 49b4586 
Remi Meier ff3c660 
Remi Meier 590a082 
Remi Meier 9fe7595 
Remi Meier 49b4586 


Remi Meier 9fe7595 







Remi Meier b908712 
Remi Meier 0874e8e 
Remi Meier bfeb8fb 
Remi Meier 49b4586 
Remi Meier 590a082 
Remi Meier b908712 
Remi Meier bfeb8fb 
Remi Meier 590a082 


Remi Meier bfeb8fb 


Remi Meier ff3c660 
Remi Meier bfeb8fb 



Remi Meier 535f5ae 
Remi Meier 590a082 
Remi Meier 9f5d327 

Remi Meier b908712 
Remi Meier 535f5ae 






Remi Meier 9f5d327 



































Remi Meier 49b4586 
Remi Meier b908712 
Remi Meier bfeb8fb 
Remi Meier 590a082 



Remi Meier ff3c660 


Remi Meier bfeb8fb 

Remi Meier ff3c660 



Remi Meier bfeb8fb 
Remi Meier 590a082 
#!/usr/bin/python

##########################################################
""" TODO: print thread-descriptor info on commit/abort """
##########################################################

import matplotlib
matplotlib.use('gtkagg')

args = None
import matplotlib.pyplot as plt
# import pprint - slow as hell
from stmlogparser import parse, EventTypes


########## DRAWING STUFF ##########

BOX_HEIGHT = 0.8
HALF_HEIGHT = 0.1 + BOX_HEIGHT / 2
QUARTER_HEIGHT = 0.1 + BOX_HEIGHT / 4

def plot_boxes(boxes, y, ax):
    coords = [(x, w) for x, w, c, i in boxes]
    colors = [c for x, w, c, i in boxes]
    bars = ax.broken_barh(coords, (y+0.1, BOX_HEIGHT),
                          facecolors=colors,
                          picker=True, antialiased=False, rasterized=True)

    bars.boxes = boxes

def plot_hlines(hlines, y, ax):
    args = [[[x1, x2], [y+HALF_HEIGHT, y+HALF_HEIGHT], color] for
            x1, x2, color in hlines]
    # flatten:
    args = [item for sublist in args for item in sublist]
    ax.plot(*args, linewidth=3, antialiased=False, rasterized=True)

####################################

def add_box(boxes, x1, x2, color, info):
    boxes.append((x1, x2-x1, color, info))

def add_hline(hlines, x1, x2, color):
    hlines.append((x1, x2, color))


def add_transaction(boxes, hlines, inited, inevitabled,
                     ended, aborted, atomics, info=""):
    assert inited != None

    if inevitabled != None:
        add_box(boxes, inited, inevitabled, 'b', info)
        add_box(boxes, inevitabled, ended, 'orange', info)
    elif not aborted:
        add_box(boxes, inited, ended, 'g', info)
    else:
        add_box(boxes, inited, ended, 'r', info)

    for start, end in atomics:
        add_hline(hlines, start, end, 'magenta')


def plot_logs(logs, ax):
    plt.ion()
    for tid in logs.keys():
        plt.draw()
        plt.show()

        inited = None
        inevitabled = None
        info = []
        start_time = 0
        end_time = 0
        boxes = []
        hlines = []
        atomics = []
        should_commits = []
        current_atomic = 0
        program_aborted = None
        for time, kind, line_dict in logs[tid]:
            if args.atomic or kind not in (EventTypes.INC_ATOMIC,
                                           EventTypes.DEC_ATOMIC):
                info.append(str(line_dict))

            if kind == EventTypes.INIT_TRANSACTION:
                inited = time
                info = ["Thread: %s\n%s" % (tid, str(line_dict))]
            elif kind == EventTypes.MAKE_INEVITABLE:
                if not inevitabled: inevitabled = time
            elif kind == EventTypes.COMMIT_TRANSACTION:
                add_transaction(boxes, hlines, inited, inevitabled,
                                time, False,
                                atomics, "\n".join(info))
                inited, inevitabled = None, None
            elif kind in (EventTypes.ABORT_TRANSACTION,
                          EventTypes.INEVITABLE_INSIDE_ATOMIC):
                if kind == EventTypes.INEVITABLE_INSIDE_ATOMIC:
                    program_aborted = time
                if current_atomic and args.atomic:
                    atomics[-1] = (atomics[-1][0], time)
                    current_atomic = 0
                add_transaction(boxes, hlines, inited, inevitabled,
                                time, True,
                                atomics, "\n".join(info))
                inited, inevitabled = None, None
            elif kind == EventTypes.INC_ATOMIC:
                if current_atomic == 0 and args.atomic:
                    atomics.append((time,))
                current_atomic += 1
            elif kind == EventTypes.DEC_ATOMIC:
                current_atomic -= 1
                if current_atomic == 0 and args.atomic:
                    atomics[-1] = (atomics[-1][0], time)
            elif kind == EventTypes.DESCRIPTOR_INIT:
                start_time = time
            elif kind == EventTypes.DESCRIPTOR_DONE:
                k = ax.plot(start_time, tid+HALF_HEIGHT, 'c>',
                            time, tid+HALF_HEIGHT, 'c<', markersize=8,
                            picker=True, antialiased=False, rasterized=True)
                [setattr(m, "info", str(tid)) for m in k]
                end_time = time
            elif kind == EventTypes.SHOULD_COMMIT:
                should_commits.append(time)

        if current_atomic and args.atomic:
            print "ERROR: Finished transaction is still atomic"

        plot_boxes(boxes, tid, ax)
        plot_hlines(hlines, tid, ax)

        if should_commits:
            ax.plot(should_commits, [tid+QUARTER_HEIGHT] * len(should_commits),
                    'y+', mew=2, markersize=8,
                    antialiased=False, rasterized=True)

        if end_time == 0:
            k = ax.plot(start_time, tid+HALF_HEIGHT, 'c>',
                        time, tid+HALF_HEIGHT, 'y*', markersize=8,
                        picker=True, antialiased=False, rasterized=True)
            [setattr(m, "info", str(tid)) for m in k]

        if program_aborted is not None:
            k = ax.plot(program_aborted, tid+HALF_HEIGHT, 'wo',
                        markersize=15, mew=3, mec='r',
                        picker=True, antialiased=False, rasterized=True)
            [setattr(m, "info", str(tid)) for m in k]

    plt.ioff()


def onpick(event):
    if hasattr(event.artist, "info"):
        print "== pick ==\n", event.artist.info
    if hasattr(event.artist, "boxes"):
        x = event.mouseevent.xdata
        for x1, w, c, i in event.artist.boxes:
            if x >= x1 and x <= x1+w:
                print "== pick ==\n", i
                break
        else:
            print "== pick ==\nCould not find info"


############## MAIN ################

def main():
    global fig

    fig = plt.figure()
    ax = fig.add_subplot(111)

    print "Parse..."
    logs = parse(args.file)
    print "Parsed."

    print "Draw..."
    plot_logs(logs, ax)
    print "Drawn."

    plt.xlabel("Runtime [s]")
    plt.ylabel("Thread")
    plt.yticks([r+0.5 for r in range(len(logs))],
               range(1, len(logs)+1))

    left = min([l[0][0] for l in logs.values()])
    right = max([l[-1][0] for l in logs.values()])
    #left, right = ax.get_xlim()
    ax.set_xlim((left, right))
    xticks = ax.get_xticks()
    ax.set_xticklabels(["%.2f" % ((t - left) * 1e-6,) for t in xticks])

    # legend-drawing
    from matplotlib.font_manager import FontProperties
    fontP = FontProperties()
    fontP.set_size('small')

    from matplotlib.patches import Rectangle
    from matplotlib.lines import  Line2D
    h = []; l=[]
    l += ['Successful Transaction']; h += [Rectangle((0, 0), 1, 1, fc="g")]
    l += ['Transaction turning inevitable']
    h += [Rectangle((0, 0), 1, 1, fc="b")]
    l += ['Transaction turned inevitable']
    h += [Rectangle((0, 0), 1, 1, fc="orange")]
    l += ['Aborted Transaction']; h += [Rectangle((0, 0), 1, 1, fc="r")]
    l += ['Thread Start']
    h += [Line2D((0,0),(0,0), marker='>', mfc='c', ls='', ms=8)]
    l += ['Thread End']
    h += [Line2D((0,0),(0,0), marker='<', mfc='c', ls='', ms=8)]
    l += ['Thread Continuing']
    h += [Line2D((0,0),(0,0), marker='*', mfc='y', ls='', ms=8)]
    l += ['Program Abort']
    h += [Line2D((0,0),(0,0), marker='o', mfc='w', ls='', ms=15, mew=3,mec='r')]
    l += ['Should Commit']
    h += [Line2D((0,0),(0,0), marker='+', mec='y', ls='', ms=8, mew=2,)]
    if args.atomic:
        l += ['Atomic block']
        h += [Line2D((0,0),(0,0), c='magenta', lw=3)]

    box = ax.get_position()
    ax.set_position([box.x0, box.y0, box.width * 0.8, box.height])

    ax.legend(h, l, numpoints=1,
              bbox_to_anchor=(1.01, 1), loc=2,
              prop=fontP)

    # event connect
    fig.canvas.mpl_connect('pick_event', onpick)

    plt.draw()
    plt.show()


if __name__ == "__main__":
    import argparse

    parser = argparse.ArgumentParser(description='Plot stm log files')
    parser.add_argument('file', help='logfile to parse')
    parser.add_argument('--atomic', action='store_const',
                        const=True, default=False,
                        help="plot atomic phases (slower)")

    args = parser.parse_args()

    main()
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.