Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Linux/tools/perf/scripts/python/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 11 kB image not shown  

Quelle  sched-migration.py   Sprache: Python

 
# Cpu task migration overview toy
#
# Copyright (C) 2010 Frederic Weisbecker <fweisbec@gmail.com>
#
# perf script event handlers have been generated by perf script -g python
#
# This software is distributed under the terms of the GNU General
# Public License ("GPL") version 2 as published by the Free Software
# Foundation.
from __future__ import print_function

import os
import sys

from collections import defaultdict
try:
 from UserList import UserList
except ImportError:
 # Python 3: UserList moved to the collections package
 from collections import UserList

sys.path.append(os.environ['PERF_EXEC_PATH'] + \
 '/scripts/python/Perf-Trace-Util/lib/Perf/Trace')
sys.path.append('scripts/python/Perf-Trace-Util/lib/Perf/Trace')

from perf_trace_context import *
from Core import *
from SchedGui import *


threads = { 0 : "idle"}

def thread_name(pid):
 return "%s:%d" % (threads[pid], pid)

class RunqueueEventUnknown:
 @staticmethod
 def color():
  return None

 def __repr__(self):
  return "unknown"

class RunqueueEventSleep:
 @staticmethod
 def color():
  return (0, 0, 0xff)

 def __init__(self, sleeper):
  self.sleeper = sleeper

 def __repr__(self):
  return "%s gone to sleep" % thread_name(self.sleeper)

class RunqueueEventWakeup:
 @staticmethod
 def color():
  return (0xff, 0xff, 0)

 def __init__(self, wakee):
  self.wakee = wakee

 def __repr__(self):
  return "%s woke up" % thread_name(self.wakee)

class RunqueueEventFork:
 @staticmethod
 def color():
  return (0, 0xff, 0)

 def __init__(self, child):
  self.child = child

 def __repr__(self):
  return "new forked task %s" % thread_name(self.child)

class RunqueueMigrateIn:
 @staticmethod
 def color():
  return (0, 0xf0, 0xff)

 def __init__(self, new):
  self.new = new

 def __repr__(self):
  return "task migrated in %s" % thread_name(self.new)

class RunqueueMigrateOut:
 @staticmethod
 def color():
  return (0xff, 0, 0xff)

 def __init__(self, old):
  self.old = old

 def __repr__(self):
  return "task migrated out %s" % thread_name(self.old)

class RunqueueSnapshot:
 def __init__(self, tasks = [0], event = RunqueueEventUnknown()):
  self.tasks = tuple(tasks)
  self.event = event

 def sched_switch(self, prev, prev_state, next):
  event = RunqueueEventUnknown()

  if taskState(prev_state) == "R" and next in self.tasks \
   and prev in self.tasks:
   return self

  if taskState(prev_state) != "R":
   event = RunqueueEventSleep(prev)

  next_tasks = list(self.tasks[:])
  if prev in self.tasks:
   if taskState(prev_state) != "R":
    next_tasks.remove(prev)
  elif taskState(prev_state) == "R":
   next_tasks.append(prev)

  if next not in next_tasks:
   next_tasks.append(next)

  return RunqueueSnapshot(next_tasks, event)

 def migrate_out(self, old):
  if old not in self.tasks:
   return self
  next_tasks = [task for task in self.tasks if task != old]

  return RunqueueSnapshot(next_tasks, RunqueueMigrateOut(old))

 def __migrate_in(self, new, event):
  if new in self.tasks:
   self.event = event
   return self
  next_tasks = self.tasks[:] + tuple([new])

  return RunqueueSnapshot(next_tasks, event)

 def migrate_in(self, new):
  return self.__migrate_in(new, RunqueueMigrateIn(new))

 def wake_up(self, new):
  return self.__migrate_in(new, RunqueueEventWakeup(new))

 def wake_up_new(self, new):
  return self.__migrate_in(new, RunqueueEventFork(new))

 def load(self):
  """ Provide the number of tasks on the runqueue.
      Don't count idle"""
  return len(self.tasks) - 1

 def __repr__(self):
  ret = self.tasks.__repr__()
  ret += self.origin_tostring()

  return ret

class TimeSlice:
 def __init__(self, start, prev):
  self.start = start
  self.prev = prev
  self.end = start
  # cpus that triggered the event
  self.event_cpus = []
  if prev is not None:
   self.total_load = prev.total_load
   self.rqs = prev.rqs.copy()
  else:
   self.rqs = defaultdict(RunqueueSnapshot)
   self.total_load = 0

 def __update_total_load(self, old_rq, new_rq):
  diff = new_rq.load() - old_rq.load()
  self.total_load += diff

 def sched_switch(self, ts_list, prev, prev_state, next, cpu):
  old_rq = self.prev.rqs[cpu]
  new_rq = old_rq.sched_switch(prev, prev_state, next)

  if old_rq is new_rq:
   return

  self.rqs[cpu] = new_rq
  self.__update_total_load(old_rq, new_rq)
  ts_list.append(self)
  self.event_cpus = [cpu]

 def migrate(self, ts_list, new, old_cpu, new_cpu):
  if old_cpu == new_cpu:
   return
  old_rq = self.prev.rqs[old_cpu]
  out_rq = old_rq.migrate_out(new)
  self.rqs[old_cpu] = out_rq
  self.__update_total_load(old_rq, out_rq)

  new_rq = self.prev.rqs[new_cpu]
  in_rq = new_rq.migrate_in(new)
  self.rqs[new_cpu] = in_rq
  self.__update_total_load(new_rq, in_rq)

  ts_list.append(self)

  if old_rq is not out_rq:
   self.event_cpus.append(old_cpu)
  self.event_cpus.append(new_cpu)

 def wake_up(self, ts_list, pid, cpu, fork):
  old_rq = self.prev.rqs[cpu]
  if fork:
   new_rq = old_rq.wake_up_new(pid)
  else:
   new_rq = old_rq.wake_up(pid)

  if new_rq is old_rq:
   return
  self.rqs[cpu] = new_rq
  self.__update_total_load(old_rq, new_rq)
  ts_list.append(self)
  self.event_cpus = [cpu]

 def next(self, t):
  self.end = t
  return TimeSlice(t, self)

class TimeSliceList(UserList):
 def __init__(self, arg = []):
  self.data = arg

 def get_time_slice(self, ts):
  if len(self.data) == 0:
   slice = TimeSlice(ts, TimeSlice(-1, None))
  else:
   slice = self.data[-1].next(ts)
  return slice

 def find_time_slice(self, ts):
  start = 0
  end = len(self.data)
  found = -1
  searching = True
  while searching:
   if start == end or start == end - 1:
    searching = False

   i = (end + start) / 2
   if self.data[i].start <= ts and self.data[i].end >= ts:
    found = i
    end = i
    continue

   if self.data[i].end < ts:
    start = i

   elif self.data[i].start > ts:
    end = i

  return found

 def set_root_win(self, win):
  self.root_win = win

 def mouse_down(self, cpu, t):
  idx = self.find_time_slice(t)
  if idx == -1:
   return

  ts = self[idx]
  rq = ts.rqs[cpu]
  raw = "CPU: %d\n" % cpu
  raw += "Last event : %s\n" % rq.event.__repr__()
  raw += "Timestamp : %d.%06d\n" % (ts.start / (10 ** 9), (ts.start % (10 ** 9)) / 1000)
  raw += "Duration : %6d us\n" % ((ts.end - ts.start) / (10 ** 6))
  raw += "Load = %d\n" % rq.load()
  for t in rq.tasks:
   raw += "%s \n" % thread_name(t)

  self.root_win.update_summary(raw)

 def update_rectangle_cpu(self, slice, cpu):
  rq = slice.rqs[cpu]

  if slice.total_load != 0:
   load_rate = rq.load() / float(slice.total_load)
  else:
   load_rate = 0

  red_power = int(0xff - (0xff * load_rate))
  color = (0xff, red_power, red_power)

  top_color = None

  if cpu in slice.event_cpus:
   top_color = rq.event.color()

  self.root_win.paint_rectangle_zone(cpu, color, top_color, slice.start, slice.end)

 def fill_zone(self, start, end):
  i = self.find_time_slice(start)
  if i == -1:
   return

  for i in range(i, len(self.data)):
   timeslice = self.data[i]
   if timeslice.start > end:
    return

   for cpu in timeslice.rqs:
    self.update_rectangle_cpu(timeslice, cpu)

 def interval(self):
  if len(self.data) == 0:
   return (0, 0)

  return (self.data[0].start, self.data[-1].end)

 def nr_rectangles(self):
  last_ts = self.data[-1]
  max_cpu = 0
  for cpu in last_ts.rqs:
   if cpu > max_cpu:
    max_cpu = cpu
  return max_cpu


class SchedEventProxy:
 def __init__(self):
  self.current_tsk = defaultdict(lambda : -1)
  self.timeslices = TimeSliceList()

 def sched_switch(self, headers, prev_comm, prev_pid, prev_prio, prev_state,
    next_comm, next_pid, next_prio):
  """ Ensure the task we sched out this cpu is really the one
      we logged. Otherwise we may have missed traces """

  on_cpu_task = self.current_tsk[headers.cpu]

  if on_cpu_task != -1 and on_cpu_task != prev_pid:
   print("Sched switch event rejected ts: %s cpu: %d prev: %s(%d) next: %s(%d)" % \
    headers.ts_format(), headers.cpu, prev_comm, prev_pid, next_comm, next_pid)

  threads[prev_pid] = prev_comm
  threads[next_pid] = next_comm
  self.current_tsk[headers.cpu] = next_pid

  ts = self.timeslices.get_time_slice(headers.ts())
  ts.sched_switch(self.timeslices, prev_pid, prev_state, next_pid, headers.cpu)

 def migrate(self, headers, pid, prio, orig_cpu, dest_cpu):
  ts = self.timeslices.get_time_slice(headers.ts())
  ts.migrate(self.timeslices, pid, orig_cpu, dest_cpu)

 def wake_up(self, headers, comm, pid, success, target_cpu, fork):
  if success == 0:
   return
  ts = self.timeslices.get_time_slice(headers.ts())
  ts.wake_up(self.timeslices, pid, target_cpu, fork)


def trace_begin():
 global parser
 parser = SchedEventProxy()

def trace_end():
 app = wx.App(False)
 timeslices = parser.timeslices
 frame = RootFrame(timeslices, "Migration")
 app.MainLoop()

def sched__sched_stat_runtime(event_name, context, common_cpu,
 common_secs, common_nsecs, common_pid, common_comm,
 common_callchain, comm, pid, runtime, vruntime):
 pass

def sched__sched_stat_iowait(event_name, context, common_cpu,
 common_secs, common_nsecs, common_pid, common_comm,
 common_callchain, comm, pid, delay):
 pass

def sched__sched_stat_sleep(event_name, context, common_cpu,
 common_secs, common_nsecs, common_pid, common_comm,
 common_callchain, comm, pid, delay):
 pass

def sched__sched_stat_wait(event_name, context, common_cpu,
 common_secs, common_nsecs, common_pid, common_comm,
 common_callchain, comm, pid, delay):
 pass

def sched__sched_process_fork(event_name, context, common_cpu,
 common_secs, common_nsecs, common_pid, common_comm,
 common_callchain, parent_comm, parent_pid, child_comm, child_pid):
 pass

def sched__sched_process_wait(event_name, context, common_cpu,
 common_secs, common_nsecs, common_pid, common_comm,
 common_callchain, comm, pid, prio):
 pass

def sched__sched_process_exit(event_name, context, common_cpu,
 common_secs, common_nsecs, common_pid, common_comm,
 common_callchain, comm, pid, prio):
 pass

def sched__sched_process_free(event_name, context, common_cpu,
 common_secs, common_nsecs, common_pid, common_comm,
 common_callchain, comm, pid, prio):
 pass

def sched__sched_migrate_task(event_name, context, common_cpu,
 common_secs, common_nsecs, common_pid, common_comm,
 common_callchain, comm, pid, prio, orig_cpu,
 dest_cpu):
 headers = EventHeaders(common_cpu, common_secs, common_nsecs,
    common_pid, common_comm, common_callchain)
 parser.migrate(headers, pid, prio, orig_cpu, dest_cpu)

def sched__sched_switch(event_name, context, common_cpu,
 common_secs, common_nsecs, common_pid, common_comm, common_callchain,
 prev_comm, prev_pid, prev_prio, prev_state,
 next_comm, next_pid, next_prio):

 headers = EventHeaders(common_cpu, common_secs, common_nsecs,
    common_pid, common_comm, common_callchain)
 parser.sched_switch(headers, prev_comm, prev_pid, prev_prio, prev_state,
    next_comm, next_pid, next_prio)

def sched__sched_wakeup_new(event_name, context, common_cpu,
 common_secs, common_nsecs, common_pid, common_comm,
 common_callchain, comm, pid, prio, success,
 target_cpu):
 headers = EventHeaders(common_cpu, common_secs, common_nsecs,
    common_pid, common_comm, common_callchain)
 parser.wake_up(headers, comm, pid, success, target_cpu, 1)

def sched__sched_wakeup(event_name, context, common_cpu,
 common_secs, common_nsecs, common_pid, common_comm,
 common_callchain, comm, pid, prio, success,
 target_cpu):
 headers = EventHeaders(common_cpu, common_secs, common_nsecs,
    common_pid, common_comm, common_callchain)
 parser.wake_up(headers, comm, pid, success, target_cpu, 0)

def sched__sched_wait_task(event_name, context, common_cpu,
 common_secs, common_nsecs, common_pid, common_comm,
 common_callchain, comm, pid, prio):
 pass

def sched__sched_kthread_stop_ret(event_name, context, common_cpu,
 common_secs, common_nsecs, common_pid, common_comm,
 common_callchain, ret):
 pass

def sched__sched_kthread_stop(event_name, context, common_cpu,
 common_secs, common_nsecs, common_pid, common_comm,
 common_callchain, comm, pid):
 pass

def trace_unhandled(event_name, context, event_fields_dict):
 pass

Messung V0.5
C=88 H=96 G=91

¤ Dauer der Verarbeitung: 0.4 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.