sbsv2/raptor/bin/timelines.py
changeset 620 ad8ffc8e1982
parent 591 22486c9c7b15
equal deleted inserted replaced
585:238f4cb8391f 620:ad8ffc8e1982
       
     1 #
       
     2 # Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 # All rights reserved.
       
     4 # This component and the accompanying materials are made available
       
     5 # under the terms of the License "Eclipse Public License v1.0"
       
     6 # which accompanies this distribution, and is available
       
     7 # at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 #
       
     9 # Initial Contributors:
       
    10 # Nokia Corporation - initial contribution.
       
    11 #
       
    12 # Contributors:
       
    13 #
       
    14 # Description: 
       
    15 # 
       
    16 # Raptor log visualisation program. Takes a raptor log as standard input
       
    17 # and displays timelines that represent build progress and 
       
    18 # how much actual parallelism there is in the build.
       
    19 # This program requires the pygame and PyOpenGL modules.
       
    20 
       
    21 from OpenGL.GL import *
       
    22 from OpenGL.GLU import *
       
    23 import pygame
       
    24 from pygame.locals import *
       
    25 import time
       
    26 
       
    27 class Timeline(object):
       
    28 	"""A bar representing a number of recipes which were executed in 
       
    29 	   time sequence.  There is no guarantee about what host but in 
       
    30 	   theory they could have been executed on the same host."""
       
    31 
       
    32 	globalmax = 2.0
       
    33 
       
    34 	def __init__(self,ylevel):
       
    35 		self.maxtime = 0.0
       
    36 		self.recipes = []
       
    37 		self.ylevel = ylevel
       
    38 
       
    39 	def append(self, recipe):
       
    40 		"" add this recipe to this timeline if it happens after the latest recipe already in the timeline ""
       
    41 		if recipe.starttime + recipe.duration > self.maxtime:
       
    42 			self.maxtime = recipe.starttime + recipe.duration
       
    43 			if self.maxtime > Timeline.globalmax:
       
    44 				Timeline.globalmax = self.maxtime 
       
    45 		else:
       
    46 			pass
       
    47 
       
    48 		self.recipes.append(recipe)
       
    49 
       
    50 	def draw(self):
       
    51 		glLoadIdentity()
       
    52 		self.xscale = 4.0 / Timeline.globalmax
       
    53 
       
    54     		glTranslatef(-2.0, -1.5, -6.0)
       
    55 		count = 0
       
    56 		for r in self.recipes:
       
    57 			if count % 2 == 0:
       
    58 				coloff=0.8
       
    59 			else:
       
    60 				coloff = 1.0
       
    61 
       
    62 			count += 1
       
    63 			r.draw(self.xscale, self.ylevel, coloff)
       
    64 
       
    65 class Recipe(object):
       
    66 	"""Represents a task completed in a raptor build. 
       
    67 	   Drawn as a colour-coded bar with different 
       
    68 	   colours for the various recipe types."""
       
    69 	STAT_OK = 0
       
    70 	colours = {
       
    71 		'compile': (0.5,0.5,1.0),
       
    72 		'compile2object': (0.5,0.5,1.0),
       
    73 		'win32compile2object': (0.5,0.5,1.0),
       
    74 		'tools2linkexe': (0.5,1.0,0.5),
       
    75 		'link': (0.5,1.0,0.5),
       
    76 		'linkandpostlink': (0.5,1.0,0.5),
       
    77 		'win32stageonelink': (0.5,1.0,0.5),
       
    78 		'tools2lib': (0.5,1.0,1.0),
       
    79 		'win32stagetwolink': (1.0,0.1,1.0),
       
    80 		'postlink': (1.0,0.5,1.0)
       
    81 		}
       
    82 
       
    83 	def __init__(self, starttime, duration, name, status):
       
    84 		self.starttime = starttime
       
    85 		self.duration = duration
       
    86 		self.status = status
       
    87 		self.colour = (1.0, 1.0, 1.0)
       
    88 		if name in Recipe.colours:
       
    89 			self.colour = Recipe.colours[name]
       
    90 		else:
       
    91 			self.colour = (1.0,1.0,1.0)
       
    92 		self.name = name 
       
    93 
       
    94 	def draw(self, scale, ylevel, coloff):
       
    95 		if self.status == Recipe.STAT_OK:
       
    96 			glColor4f(self.colour[0]*coloff, self.colour[1]*coloff, self.colour[2]*coloff,0.2)
       
    97 		else:
       
    98 			glColor4f(1.0*coloff, 0.6*coloff, 0.6*coloff,0.2)
       
    99 
       
   100 
       
   101 		x = self.starttime * scale
       
   102 		y = ylevel
       
   103 		x2 = x + self.duration * scale
       
   104 		y2 = ylevel + 0.2
       
   105 		glBegin(GL_QUADS)
       
   106 		glVertex3f(x, y, 0)
       
   107 		glVertex3f(x, y2, 0)
       
   108 		glVertex3f(x2, y2, 0)
       
   109 		glVertex3f(x2, y, 0)
       
   110 		glEnd()
       
   111 
       
   112 
       
   113 def resize((width, height)):
       
   114 	if height==0:
       
   115 		height=1
       
   116 	glViewport(0, 0, width, height)
       
   117 	glMatrixMode(GL_PROJECTION)
       
   118 	glLoadIdentity()
       
   119 	gluPerspective(45, 1.0*width/height, 0.1, 100.0)
       
   120 	glMatrixMode(GL_MODELVIEW)
       
   121 	glLoadIdentity()
       
   122 
       
   123 def init():
       
   124 	glShadeModel(GL_SMOOTH)
       
   125 	glClearColor(0.0, 0.0, 0.0, 0.0)
       
   126 	glClearDepth(1.0)
       
   127 	glEnable(GL_DEPTH_TEST)
       
   128 	glDepthFunc(GL_LEQUAL)
       
   129 	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)
       
   130 
       
   131 
       
   132 import sys
       
   133 import re
       
   134 
       
   135 def main():
       
   136 
       
   137 	video_flags = OPENGL|DOUBLEBUF
       
   138 
       
   139 	pygame.init()
       
   140 	pygame.display.set_mode((800,600), video_flags)
       
   141 
       
   142 	resize((800,600))
       
   143 	init()
       
   144 
       
   145 	frames = 0
       
   146 	ticks = pygame.time.get_ticks()
       
   147 
       
   148 
       
   149 	lines = 4
       
   150 	timelines = []
       
   151 	ylevel = 0.0
       
   152 	for i in xrange(0,4):
       
   153 		ylevel += 0.6 
       
   154 		timelines.append(Timeline(ylevel))
       
   155 
       
   156 	f = sys.stdin
       
   157 
       
   158 	recipe_re = re.compile(".*<recipe name='([^']+)'.*")
       
   159 	time_re = re.compile(".*<time start='([0-9]+\.[0-9]+)' *elapsed='([0-9]+\.[0-9]+)'.*")
       
   160 	status_re = re.compile(".*<status exit='([^']*)'.*")
       
   161 
       
   162 	alternating = 0
       
   163 	start_time = 0.0
       
   164 
       
   165 	
       
   166 	for l in f.xreadlines():
       
   167 		l2 = l.rstrip("\n")
       
   168 		rm = recipe_re.match(l2)
       
   169 
       
   170 		if rm is not None:
       
   171 			rname = rm.groups()[0]
       
   172 			continue
       
   173 
       
   174 
       
   175 		tm = time_re.match(l2)
       
   176 		if tm is not None:
       
   177 			s = float(tm.groups()[0])
       
   178 			elapsed = float(tm.groups()[1])
       
   179 
       
   180 			if start_time == 0.0:
       
   181 				start_time = s
       
   182 
       
   183 			s -= start_time
       
   184 
       
   185 			continue
       
   186 
       
   187 		sm = status_re.match(l2)
       
   188 
       
   189 		if sm is None:
       
   190 			continue
       
   191 
       
   192 		if sm.groups()[0] == 'ok':
       
   193 			status = 0
       
   194 		else:
       
   195 			status = int(sm.groups()[0])
       
   196 
       
   197 		olddiff = 999999999.0
       
   198 		tnum = 0
       
   199 		for t in timelines:
       
   200 			newdiff = s - t.maxtime
       
   201 			if newdiff < 0.0:
       
   202 				continue
       
   203 			if olddiff > newdiff:
       
   204 				dest_timeline = t
       
   205 				olddiff = newdiff
       
   206 			tnum += 1
       
   207 
       
   208 		dest_timeline.append(Recipe(s, elapsed, rname, status))
       
   209 		event = pygame.event.poll()
       
   210 		if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE):
       
   211 			break
       
   212 
       
   213 		glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
       
   214 		for t in timelines:
       
   215 			t.draw()
       
   216 		pygame.display.flip()
       
   217 
       
   218 		frames = frames+1
       
   219 
       
   220 	print "fps:  %de" % ((frames*1000)/(pygame.time.get_ticks()-ticks))
       
   221 	event = pygame.event.wait()
       
   222 
       
   223 
       
   224 if __name__ == '__main__': main()