| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168 |
- #!/usr/bin/env python
- # coding: utf-8
- import sys, os
- import matplotlib
- matplotlib.use('Agg')
- from pylab import *
- from matplotlib.transforms import TransformedBbox
- class EventFactory(object):
- #CPU time pid cpu (si pid == -1 -> idle)
- cpu_event= lambda x: Event(x[0],EventFactory.Events.keys().index(x[0]),int(x[1]),int(x[2]),int(x[3]))
- #EVENT time pid
- other_event= lambda x: Event(x[0],EventFactory.Events.keys().index(x[0]),int(x[1]),int(x[2]),-1)
- #CONTEXT CPU cpu time (se pone pid == -2)
- context_switch_event= lambda x: Event(x[0] ,EventFactory.Events.keys().index(x[0]),int(x[3]),-2,int(x[2]))
- Events = {'LOAD': other_event,
- 'CPU':cpu_event,
- 'BLOCK': other_event,
- 'UNBLOCK': other_event,
- 'DEADLINE': other_event,
- 'EXIT': other_event,
- 'CONTEXT':context_switch_event,
- 'WAITING':None,
- 'NOT_LOAD': None,
- 'CPU_BLOCK': None}
- @classmethod
- def get_event(cls, event_line):
- splited_event_line= event_line.split()
- if splited_event_line[0] in EventFactory.Events.keys():
- return EventFactory.Events[splited_event_line[0]](splited_event_line)
- else:
- return None
- class Event(object):
- def __init__(self, event_type, event_code, time, pid, core):
- self.event_type= event_type
- self.event_code= event_code
- self.time= time
- self.pid= pid
- self.core= core
- def __str__(self):
- return 'Type: ' + self.event_type + ', Code: ' + str(self.event_code) + ', Time: ' + str(self.time) + ', Pid: ' + str(self.pid) + ', Core: ' + str(self.core)
- def parseInput(fin):
- ln = 0
- result = []
- cores = 0
- pids= 0
- settings = None
- cpus_timeline= dict()
- for line in fin:
- ln += 1
- vls = line.split()
- if line and line[0] == '#':
- if line.startswith('# SETTINGS '):
- settings = line[11:].strip()
- continue
- else:
- line= line[2:].strip() # Queda --> 'CONTEXT CPU cpu time
- event= EventFactory.get_event(line)
- result.append(event)
- if event.event_type == 'CPU':
- if (cores <=event.core):
- cores = event.core+1
- if event.event_type == 'LOAD':
- if(pids <= event.pid):
- pids = event.pid +1
- return settings, result, cores, pids
- def dataGathering(data, cores, pids):
- core_timeline= dict() # core: list(pids) NOTA: se supone que en cada tick hay un pid
- block_lapse= dict()
- for event in data:
- #core_time
- if event.core != -1:
- if event.core not in core_timeline: core_timeline[event.core]= []
- core_timeline[event.core].append(event.pid)
- return core_timeline
- def draw_cores_timeline_gannt(cores_timeline, filename):
- ''' pre: cores_timeline = {core: list(pid) } '''
- # Necesitaria tener la info algo asi como
- # core: {pid: ini_1,fin_1,ini_2,fin_2} (es decir por intervalos)
- # broken_barh necesita (inicio, longitud)
- colors={'pid':'#c0ffc0','switch':'#b7b7f7', 'idle':'#d0d0d0'}
- fig= figure(figsize=(11.8,8.3))
- ax = fig.add_subplot(111)
- title('Tareas en Core por tiempo')
- yticks(cores_timeline.keys())
- # ax.xaxis.set_major_locator(
- ax.xaxis.set_major_locator( IndexLocator(2,1) )
- #xticks(range(len(cores_timeline[0])),range(0,len(cores_timeline[0]),5))
- xlabel('Tiempo')
- ylabel('Core')
- ylim((-1,len(cores_timeline.keys())))
- ax.grid(True)
- for core in cores_timeline:
- pids_by_time= cores_timeline[core]
- intervals= dict()
- last_pid= None
- for time in range(len(pids_by_time)):
- if last_pid != pids_by_time[time]:
- last_pid = pids_by_time[time]
- if last_pid not in intervals: intervals[last_pid]= []
- intervals[last_pid].append((time, 1))
- #intervals.push((last_pid,time,1))
- else:
- #pid, time, interval_size= intervals.pop()
- #intervals.push((pid, time, interval_size+1))
- time, interval_size= intervals[last_pid].pop()
- intervals[last_pid].append((time, interval_size+1))
- for pid in intervals:
- if pid >= 0:
- rect= ax.broken_barh(intervals[pid], (core-0.25, 0.5), facecolor=colors['pid'])
- for init, size in intervals[pid]:
- ax.text(init+(size/2.0),core, str(pid), ha="center", va="center", size=9, weight='bold')
- elif pid == -1:
- rect= ax.broken_barh(intervals[pid], (core-0.25, 0.5), facecolor=colors['idle'])
- elif pid == -2:
- rect= ax.broken_barh(intervals[pid], (core-0.25, 0.5), facecolor=colors['switch'])
- else:
- print 'ERROR!'
- tarea_dummy = Rectangle((0, 0), 1, 1, fc=colors['pid'])
- switch_dummy = Rectangle((0, 0), 1, 1, fc=colors['switch'])
- idle_dummy = Rectangle((0, 0), 1, 1, fc=colors['idle'])
- legend([tarea_dummy, switch_dummy, idle_dummy], ['Tarea','Cambio de contexto','Inactivo'])
- tight_layout()
- fig.autofmt_xdate()
- ax.legend()
- savefig(filename+'.png', dpi=300, format='png')
- def main(argv):
- if len(argv) <= 1:
- fin = sys.stdin
- fout_cores_timeline= 'out_cores_timeline'
- else:
- fin = open(argv[1], 'r')
- preffix= argv[1]
- fout_cores_timeline= preffix + '_cores_timeline'
- print 'parsing input'
- settings, data, cores, pids = parseInput(fin)
- print 'data gathering'
- cores_timeline= dataGathering(data, cores, pids)
- print cores_timeline
- #todo dump de los datos
- print 'drawing cores timeline'
- draw_cores_timeline_gannt(cores_timeline, fout_cores_timeline)
- if __name__ == "__main__":
- main(sys.argv)
|