summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2009-01-08 13:06:31 -0200
committerArnaldo Carvalho de Melo <acme@redhat.com>2009-01-08 13:06:31 -0200
commit9fae21ee420eb4c932e3320002a90de09bed6932 (patch)
treeb2cba0198551113422250378a19d07871ca5640b
parent407315b3f248da39efa5013e9ec90c7c5616999a (diff)
downloadtuna-9fae21ee420eb4c932e3320002a90de09bed6932.tar.gz
gui: move cpuview classes to a separate file
Breaking down the complexity by compatimentalizing classes, others will follow. Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r--MANIFEST2
-rwxr-xr-xtuna-cmd.py2
-rw-r--r--tuna/gui/__init__.py14
-rw-r--r--tuna/gui/cpuview.py356
-rw-r--r--tuna/tuna_gui.py366
5 files changed, 380 insertions, 360 deletions
diff --git a/MANIFEST b/MANIFEST
index 1446850..11f9e57 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -6,6 +6,8 @@ tuna/sysfs.py
tuna/tuna.py
tuna/tuna_gui.py
tuna/tuna_gui.glade
+tuna/gui/__init__.py
+tuna/gui/cpuview.py
setup.py
rpm/SPECS/tuna.spec
MANIFEST
diff --git a/tuna-cmd.py b/tuna-cmd.py
index de042ec..0f36297 100755
--- a/tuna-cmd.py
+++ b/tuna-cmd.py
@@ -358,7 +358,7 @@ def main():
return
try:
cpus_filtered = filter and cpu_list or []
- app = tuna_gui.gui(kthreads, uthreads, cpus_filtered)
+ app = tuna_gui.main_gui(kthreads, uthreads, cpus_filtered)
app.run()
except KeyboardInterrupt:
pass
diff --git a/tuna/gui/__init__.py b/tuna/gui/__init__.py
new file mode 100644
index 0000000..9d61cbe
--- /dev/null
+++ b/tuna/gui/__init__.py
@@ -0,0 +1,14 @@
+"""
+Copyright (c) 2009 Red Hat Inc.
+
+Application Tuning GUI
+"""
+__author__ = "Arnaldo Carvalho de Melo <acme@redhat.com>"
+__license__ = "GPLv2 License"
+
+DND_TARGET_STRING = 0
+DND_TARGET_ROOTWIN = 1
+
+DND_TARGETS = [ ('STRING', 0, DND_TARGET_STRING),
+ ('text/plain', 0, DND_TARGET_STRING),
+ ('application/x-rootwin-drop', 0, DND_TARGET_ROOTWIN) ]
diff --git a/tuna/gui/cpuview.py b/tuna/gui/cpuview.py
new file mode 100644
index 0000000..3a93c62
--- /dev/null
+++ b/tuna/gui/cpuview.py
@@ -0,0 +1,356 @@
+#! /usr/bin/python
+# -*- python -*-
+# -*- coding: utf-8 -*-
+
+import pygtk
+pygtk.require("2.0")
+
+import gtk, gobject, math, os, procfs, schedutils
+from tuna import sysfs, tuna, gui
+
+def set_affinity_warning(tid, affinity):
+ dialog = gtk.MessageDialog(None,
+ gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
+ gtk.MESSAGE_WARNING,
+ gtk.BUTTONS_OK,
+ "Couldn't change the affinity of %d to %s!" % \
+ (tid, affinity))
+ dialog.run()
+ dialog.destroy()
+
+def drop_handler_move_threads_to_cpu(new_affinity, data):
+ pid_list = [ int(pid) for pid in data.split(",") ]
+
+ return tuna.move_threads_to_cpu(new_affinity, pid_list,
+ set_affinity_warning)
+
+def drop_handler_move_irqs_to_cpu(cpus, data):
+ irq_list = [ int(irq) for irq in data.split(",") ]
+ new_affinity = [ reduce(lambda a, b: a | b,
+ map(lambda cpu: 1 << cpu, cpus)), ]
+
+ for irq in irq_list:
+ tuna.set_irq_affinity(irq, new_affinity)
+
+ # FIXME: check if we really changed the affinity, but
+ # its only an optimization to avoid a needless refresh
+ # in the irqview, now we always refresh.
+ return True
+
+class cpu_socket_frame(gtk.Frame):
+
+ ( COL_FILTER, COL_CPU, COL_USAGE ) = range(3)
+
+ def __init__(self, socket, cpus, creator):
+
+ if creator.nr_sockets > 1:
+ gtk.Frame.__init__(self, "Socket %s" % socket)
+ else:
+ gtk.Frame.__init__(self)
+
+ self.socket = socket
+ self.cpus = cpus
+ self.nr_cpus = len(cpus)
+ self.creator = creator
+
+ self.list_store = gtk.ListStore(gobject.TYPE_BOOLEAN,
+ gobject.TYPE_UINT,
+ gobject.TYPE_UINT)
+
+ self.treeview = gtk.TreeView(self.list_store)
+
+ # Filter column
+ renderer = gtk.CellRendererToggle()
+ renderer.connect('toggled', self.filter_toggled, self.list_store)
+ column = gtk.TreeViewColumn('Filter', renderer, active = self.COL_FILTER)
+ self.treeview.append_column(column)
+
+ # CPU# column
+ column = gtk.TreeViewColumn('CPU', gtk.CellRendererText(),
+ text = self.COL_CPU)
+ self.treeview.append_column(column)
+
+ # CPU usage column
+ try:
+ column = gtk.TreeViewColumn('Usage', gtk.CellRendererProgress(),
+ text = self.COL_USAGE, value = self.COL_USAGE)
+ except:
+ # CellRendererProgress needs pygtk2 >= 2.6
+ column = gtk.TreeViewColumn('Usage', gtk.CellRendererText(),
+ text = self.COL_USAGE)
+ self.treeview.append_column(column)
+
+ self.add(self.treeview)
+
+ self.treeview.enable_model_drag_dest(gui.DND_TARGETS,
+ gtk.gdk.ACTION_DEFAULT)
+ self.treeview.connect("drag_data_received",
+ self.on_drag_data_received_data)
+ self.treeview.connect("button_press_event",
+ self.on_cpu_socket_frame_button_press_event)
+
+ self.drop_handlers = { "pid": (drop_handler_move_threads_to_cpu, self.creator.procview),
+ "irq": (drop_handler_move_irqs_to_cpu, self.creator.irqview), }
+
+ self.drag_dest_set(gtk.DEST_DEFAULT_ALL, gui.DND_TARGETS,
+ gtk.gdk.ACTION_DEFAULT | gtk.gdk.ACTION_MOVE)
+ self.connect("drag_data_received",
+ self.on_frame_drag_data_received_data)
+
+ def on_frame_drag_data_received_data(self, w, context, x, y,
+ selection, info, etime):
+ # Move to all CPUs in this socket
+ cpus = [ int(cpu.name[3:]) for cpu in self.cpus ]
+ # pid list, a irq list, etc
+ source, data = selection.data.split(":")
+
+ if self.drop_handlers.has_key(source):
+ if self.drop_handlers[source][0](cpus, data):
+ self.drop_handlers[source][1].refresh()
+ else:
+ print "cpu_socket_frame: unhandled drag source '%s'" % source
+
+ def on_drag_data_received_data(self, treeview, context, x, y,
+ selection, info, etime):
+ drop_info = treeview.get_dest_row_at_pos(x, y)
+
+ # pid list, a irq list, etc
+ source, data = selection.data.split(":")
+
+ if drop_info:
+ model = treeview.get_model()
+ path, position = drop_info
+ iter = model.get_iter(path)
+ cpus = [ model.get_value(iter, self.COL_CPU), ]
+ else:
+ # Move to all CPUs in this socket
+ cpus = [ int(cpu.name[3:]) for cpu in self.cpus ]
+
+ if self.drop_handlers.has_key(source):
+ if self.drop_handlers[source][0](cpus, data):
+ self.drop_handlers[source][1].refresh()
+ else:
+ print "cpu_socket_frame: unhandled drag source '%s'" % source
+
+ def refresh(self):
+ self.list_store.clear()
+ for i in range(self.nr_cpus):
+ cpu = self.cpus[i]
+ cpunr = int(cpu.name[3:])
+ usage = self.creator.cpustats[cpunr + 1].usage
+
+ iter = self.list_store.append()
+ self.list_store.set(iter,
+ self.COL_FILTER, cpunr not in self.creator.cpus_filtered,
+ self.COL_CPU, cpunr,
+ self.COL_USAGE, int(usage))
+ self.treeview.show_all()
+
+ def isolate_cpu(self, a):
+ ret = self.treeview.get_path_at_pos(self.last_x, self.last_y)
+ if not ret:
+ return
+ path, col, xpos, ypos = ret
+ if not path:
+ return
+ row = self.list_store.get_iter(path)
+ cpu = self.list_store.get_value(row, self.COL_CPU)
+
+ self.creator.isolate_cpus([cpu,])
+
+ def include_cpu(self, a):
+ ret = self.treeview.get_path_at_pos(self.last_x, self.last_y)
+ if not ret:
+ return
+ path, col, xpos, ypos = ret
+ if not path:
+ return
+ row = self.list_store.get_iter(path)
+ cpu = self.list_store.get_value(row, self.COL_CPU)
+
+ self.creator.include_cpus([cpu,])
+
+ def restore_cpu(self, a):
+
+ self.creator.restore_cpu()
+
+ def isolate_cpu_socket(self, a):
+
+ # Isolate all CPUs in this socket
+ cpus = [ int(cpu.name[3:]) for cpu in self.cpus ]
+ self.creator.isolate_cpus(cpus)
+
+ def include_cpu_socket(self, a):
+
+ # Include all CPUs in this socket
+ cpus = [ int(cpu.name[3:]) for cpu in self.cpus ]
+ self.creator.include_cpus(cpus)
+
+ def on_cpu_socket_frame_button_press_event(self, treeview, event):
+ if event.type != gtk.gdk.BUTTON_PRESS or event.button != 3:
+ return
+
+ self.last_x = int(event.x)
+ self.last_y = int(event.y)
+
+ menu = gtk.Menu()
+
+ include = gtk.MenuItem("I_nclude CPU")
+ isolate = gtk.MenuItem("_Isolate CPU")
+ if self.creator.nr_sockets > 1:
+ include_socket = gtk.MenuItem("I_nclude CPU Socket")
+ isolate_socket = gtk.MenuItem("_Isolate CPU Socket")
+ restore = gtk.MenuItem("_Restore CPU")
+
+ menu.add(include)
+ menu.add(isolate)
+ if self.creator.nr_sockets > 1:
+ menu.add(include_socket)
+ menu.add(isolate_socket)
+ menu.add(restore)
+
+ include.connect_object('activate', self.include_cpu, event)
+ isolate.connect_object('activate', self.isolate_cpu, event)
+ if self.creator.nr_sockets > 1:
+ include_socket.connect_object('activate', self.include_cpu_socket, event)
+ isolate_socket.connect_object('activate', self.isolate_cpu_socket, event)
+ if not (self.creator.previous_pid_affinities or \
+ self.creator.previous_irq_affinities):
+ restore.set_sensitive(False)
+ restore.connect_object('activate', self.restore_cpu, event)
+
+ include.show()
+ isolate.show()
+ if self.creator.nr_sockets > 1:
+ include_socket.show()
+ isolate_socket.show()
+ restore.show()
+
+ menu.popup(None, None, None, event.button, event.time)
+
+ def filter_toggled(self, cell, path, model):
+ # get toggled iter
+ iter = model.get_iter((int(path),))
+ enabled = model.get_value(iter, self.COL_FILTER)
+ cpu = model.get_value(iter, self.COL_CPU)
+
+ enabled = not enabled
+ self.creator.toggle_mask_cpu(cpu, enabled)
+
+ # set new value
+ model.set(iter, self.COL_FILTER, enabled)
+
+class cpuview:
+
+ def __init__(self, vpaned, hpaned, window, procview, irqview, cpus_filtered):
+ self.cpus = sysfs.cpus()
+ self.cpustats = procfs.cpusstats()
+ self.socket_frames = {}
+
+ self.procview = procview
+ self.irqview = irqview
+
+ vbox = window.get_child().get_child()
+ socket_ids = self.cpus.sockets.keys()
+ socket_ids.sort()
+
+ self.nr_sockets = len(socket_ids)
+ if self.nr_sockets > 1:
+ columns = math.ceil(math.sqrt(self.nr_sockets))
+ rows = math.ceil(self.nr_sockets / columns)
+ box = gtk.HBox()
+ else:
+ box = vbox
+
+ column = 1
+ for socket_id in socket_ids:
+ frame = cpu_socket_frame(socket_id,
+ self.cpus.sockets[socket_id],
+ self)
+ box.pack_start(frame, False, False)
+ self.socket_frames[socket_id] = frame
+ if self.nr_sockets > 1:
+ if column == columns:
+ vbox.pack_start(box, True, True)
+ box = gtk.HBox()
+ column = 1
+ else:
+ column += 1
+
+ window.show_all()
+
+ self.cpus_filtered = cpus_filtered
+ self.refresh()
+
+ self.previous_pid_affinities = None
+ self.previous_irq_affinities = None
+
+ req = frame.size_request()
+ # FIXME: what is the slack we have
+ # to add to every row and column?
+ width = req[0] + 16
+ height = req[1] + 20
+ if self.nr_sockets > 1:
+ width *= columns
+ height *= rows
+ vpaned.set_position(int(height))
+ hpaned.set_position(int(width))
+
+ self.timer = gobject.timeout_add(3000, self.refresh)
+
+ def isolate_cpus(self, cpus):
+ self.previous_pid_affinities, \
+ self.previous_irq_affinities = tuna.isolate_cpus(cpus, self.cpus.nr_cpus)
+
+ if self.previous_pid_affinities:
+ self.procview.refresh()
+
+ if self.previous_irq_affinities:
+ self.irqview.refresh()
+
+ def include_cpus(self, cpus):
+ self.previous_pid_affinities, \
+ self.previous_irq_affinities = tuna.include_cpus(cpus, self.cpus.nr_cpus)
+
+ if self.previous_pid_affinities:
+ self.procview.refresh()
+
+ if self.previous_irq_affinities:
+ self.irqview.refresh()
+
+ def restore_cpu(self):
+ if not (self.previous_pid_affinities or \
+ self.previous_irq_affinities):
+ return
+ affinities = self.previous_pid_affinities
+ for pid in affinities.keys():
+ try:
+ schedutils.set_affinity(pid, affinities[pid])
+ except:
+ pass
+
+ affinities = self.previous_irq_affinities
+ for irq in affinities.keys():
+ tuna.set_irq_affinity(int(irq),
+ procfs.hexbitmask(affinities[irq],
+ self.cpus.nr_cpus))
+
+ self.previous_pid_affinities = None
+ self.previous_irq_affinities = None
+
+ def toggle_mask_cpu(self, cpu, enabled):
+ if enabled:
+ if cpu in self.cpus_filtered:
+ self.cpus_filtered.remove(cpu)
+ else:
+ if cpu not in self.cpus_filtered:
+ self.cpus_filtered.append(cpu)
+
+ self.procview.toggle_mask_cpu(cpu, enabled)
+ self.irqview.toggle_mask_cpu(cpu, enabled)
+
+ def refresh(self):
+ self.cpustats.reload()
+ for frame in self.socket_frames.keys():
+ self.socket_frames[frame].refresh()
+ return True
diff --git a/tuna/tuna_gui.py b/tuna/tuna_gui.py
index 9dcec13..cce622c 100644
--- a/tuna/tuna_gui.py
+++ b/tuna/tuna_gui.py
@@ -5,9 +5,11 @@
import pygtk
pygtk.require("2.0")
-import copy, ethtool, gtk, gobject, os, pango, procfs, re, schedutils, sys, tuna
-import sysfs, math
+import copy, ethtool, gtk, gobject, os, pango, procfs, re, schedutils, sys
import gtk.glade
+import gui
+from gui.cpuview import cpuview
+import tuna
try:
from sets import Set as set
@@ -18,45 +20,9 @@ except:
# FIXME: should go to python-schedutils
( SCHED_OTHER, SCHED_FIFO, SCHED_RR, SCHED_BATCH ) = range(4)
-DND_TARGET_STRING = 0
-DND_TARGET_ROOTWIN = 1
-
-DND_TARGETS = [ ('STRING', 0, DND_TARGET_STRING),
- ('text/plain', 0, DND_TARGET_STRING),
- ('application/x-rootwin-drop', 0, DND_TARGET_ROOTWIN) ]
-
tuna_glade_dirs = [ ".", "tuna", "/usr/share/tuna" ]
tuna_glade = None
-def set_affinity_warning(tid, affinity):
- dialog = gtk.MessageDialog(None,
- gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
- gtk.MESSAGE_WARNING,
- gtk.BUTTONS_OK,
- "Couldn't change the affinity of %d to %s!" % \
- (tid, affinity))
- dialog.run()
- dialog.destroy()
-
-def drop_handler_move_threads_to_cpu(new_affinity, data):
- pid_list = [ int(pid) for pid in data.split(",") ]
-
- return tuna.move_threads_to_cpu(new_affinity, pid_list,
- set_affinity_warning)
-
-def drop_handler_move_irqs_to_cpu(cpus, data):
- irq_list = [ int(irq) for irq in data.split(",") ]
- new_affinity = [ reduce(lambda a, b: a | b,
- map(lambda cpu: 1 << cpu, cpus)), ]
-
- for irq in irq_list:
- tuna.set_irq_affinity(irq, new_affinity)
-
- # FIXME: check if we really changed the affinity, but
- # its only an optimization to avoid a needless refresh
- # in the irqview, now we always refresh.
- return True
-
def set_store_columns(store, row, new_value):
nr_columns = len(new_value)
for col in range(nr_columns):
@@ -80,324 +46,6 @@ def generate_list_store_columns_with_attr(columns):
for column in columns:
yield gobject.TYPE_UINT
-class cpu_socket_frame(gtk.Frame):
-
- ( COL_FILTER, COL_CPU, COL_USAGE ) = range(3)
-
- def __init__(self, socket, cpus, creator):
-
- if creator.nr_sockets > 1:
- gtk.Frame.__init__(self, "Socket %s" % socket)
- else:
- gtk.Frame.__init__(self)
-
- self.socket = socket
- self.cpus = cpus
- self.nr_cpus = len(cpus)
- self.creator = creator
-
- self.list_store = gtk.ListStore(gobject.TYPE_BOOLEAN,
- gobject.TYPE_UINT,
- gobject.TYPE_UINT)
-
- self.treeview = gtk.TreeView(self.list_store)
-
- # Filter column
- renderer = gtk.CellRendererToggle()
- renderer.connect('toggled', self.filter_toggled, self.list_store)
- column = gtk.TreeViewColumn('Filter', renderer, active = self.COL_FILTER)
- self.treeview.append_column(column)
-
- # CPU# column
- column = gtk.TreeViewColumn('CPU', gtk.CellRendererText(),
- text = self.COL_CPU)
- self.treeview.append_column(column)
-
- # CPU usage column
- try:
- column = gtk.TreeViewColumn('Usage', gtk.CellRendererProgress(),
- text = self.COL_USAGE, value = self.COL_USAGE)
- except:
- # CellRendererProgress needs pygtk2 >= 2.6
- column = gtk.TreeViewColumn('Usage', gtk.CellRendererText(),
- text = self.COL_USAGE)
- self.treeview.append_column(column)
-
- self.add(self.treeview)
-
- self.treeview.enable_model_drag_dest(DND_TARGETS,
- gtk.gdk.ACTION_DEFAULT)
- self.treeview.connect("drag_data_received",
- self.on_drag_data_received_data)
- self.treeview.connect("button_press_event",
- self.on_cpu_socket_frame_button_press_event)
-
- self.drop_handlers = { "pid": (drop_handler_move_threads_to_cpu, self.creator.procview),
- "irq": (drop_handler_move_irqs_to_cpu, self.creator.irqview), }
-
- self.drag_dest_set(gtk.DEST_DEFAULT_ALL, DND_TARGETS,
- gtk.gdk.ACTION_DEFAULT | gtk.gdk.ACTION_MOVE)
- self.connect("drag_data_received",
- self.on_frame_drag_data_received_data)
-
- def on_frame_drag_data_received_data(self, w, context, x, y,
- selection, info, etime):
- # Move to all CPUs in this socket
- cpus = [ int(cpu.name[3:]) for cpu in self.cpus ]
- # pid list, a irq list, etc
- source, data = selection.data.split(":")
-
- if self.drop_handlers.has_key(source):
- if self.drop_handlers[source][0](cpus, data):
- self.drop_handlers[source][1].refresh()
- else:
- print "cpu_socket_frame: unhandled drag source '%s'" % source
-
- def on_drag_data_received_data(self, treeview, context, x, y,
- selection, info, etime):
- drop_info = treeview.get_dest_row_at_pos(x, y)
-
- # pid list, a irq list, etc
- source, data = selection.data.split(":")
-
- if drop_info:
- model = treeview.get_model()
- path, position = drop_info
- iter = model.get_iter(path)
- cpus = [ model.get_value(iter, self.COL_CPU), ]
- else:
- # Move to all CPUs in this socket
- cpus = [ int(cpu.name[3:]) for cpu in self.cpus ]
-
- if self.drop_handlers.has_key(source):
- if self.drop_handlers[source][0](cpus, data):
- self.drop_handlers[source][1].refresh()
- else:
- print "cpu_socket_frame: unhandled drag source '%s'" % source
-
- def refresh(self):
- self.list_store.clear()
- for i in range(self.nr_cpus):
- cpu = self.cpus[i]
- cpunr = int(cpu.name[3:])
- usage = self.creator.cpustats[cpunr + 1].usage
-
- iter = self.list_store.append()
- self.list_store.set(iter,
- self.COL_FILTER, cpunr not in self.creator.cpus_filtered,
- self.COL_CPU, cpunr,
- self.COL_USAGE, int(usage))
- self.treeview.show_all()
-
- def isolate_cpu(self, a):
- ret = self.treeview.get_path_at_pos(self.last_x, self.last_y)
- if not ret:
- return
- path, col, xpos, ypos = ret
- if not path:
- return
- row = self.list_store.get_iter(path)
- cpu = self.list_store.get_value(row, self.COL_CPU)
-
- self.creator.isolate_cpus([cpu,])
-
- def include_cpu(self, a):
- ret = self.treeview.get_path_at_pos(self.last_x, self.last_y)
- if not ret:
- return
- path, col, xpos, ypos = ret
- if not path:
- return
- row = self.list_store.get_iter(path)
- cpu = self.list_store.get_value(row, self.COL_CPU)
-
- self.creator.include_cpus([cpu,])
-
- def restore_cpu(self, a):
-
- self.creator.restore_cpu()
-
- def isolate_cpu_socket(self, a):
-
- # Isolate all CPUs in this socket
- cpus = [ int(cpu.name[3:]) for cpu in self.cpus ]
- self.creator.isolate_cpus(cpus)
-
- def include_cpu_socket(self, a):
-
- # Include all CPUs in this socket
- cpus = [ int(cpu.name[3:]) for cpu in self.cpus ]
- self.creator.include_cpus(cpus)
-
- def on_cpu_socket_frame_button_press_event(self, treeview, event):
- if event.type != gtk.gdk.BUTTON_PRESS or event.button != 3:
- return
-
- self.last_x = int(event.x)
- self.last_y = int(event.y)
-
- menu = gtk.Menu()
-
- include = gtk.MenuItem("I_nclude CPU")
- isolate = gtk.MenuItem("_Isolate CPU")
- if self.creator.nr_sockets > 1:
- include_socket = gtk.MenuItem("I_nclude CPU Socket")
- isolate_socket = gtk.MenuItem("_Isolate CPU Socket")
- restore = gtk.MenuItem("_Restore CPU")
-
- menu.add(include)
- menu.add(isolate)
- if self.creator.nr_sockets > 1:
- menu.add(include_socket)
- menu.add(isolate_socket)
- menu.add(restore)
-
- include.connect_object('activate', self.include_cpu, event)
- isolate.connect_object('activate', self.isolate_cpu, event)
- if self.creator.nr_sockets > 1:
- include_socket.connect_object('activate', self.include_cpu_socket, event)
- isolate_socket.connect_object('activate', self.isolate_cpu_socket, event)
- if not (self.creator.previous_pid_affinities or \
- self.creator.previous_irq_affinities):
- restore.set_sensitive(False)
- restore.connect_object('activate', self.restore_cpu, event)
-
- include.show()
- isolate.show()
- if self.creator.nr_sockets > 1:
- include_socket.show()
- isolate_socket.show()
- restore.show()
-
- menu.popup(None, None, None, event.button, event.time)
-
- def filter_toggled(self, cell, path, model):
- # get toggled iter
- iter = model.get_iter((int(path),))
- enabled = model.get_value(iter, self.COL_FILTER)
- cpu = model.get_value(iter, self.COL_CPU)
-
- enabled = not enabled
- self.creator.toggle_mask_cpu(cpu, enabled)
-
- # set new value
- model.set(iter, self.COL_FILTER, enabled)
-
-class cpuview:
-
- def __init__(self, vpaned, hpaned, window, procview, irqview, cpus_filtered):
- self.cpus = sysfs.cpus()
- self.cpustats = procfs.cpusstats()
- self.socket_frames = {}
-
- self.procview = procview
- self.irqview = irqview
-
- vbox = window.get_child().get_child()
- socket_ids = self.cpus.sockets.keys()
- socket_ids.sort()
-
- self.nr_sockets = len(socket_ids)
- if self.nr_sockets > 1:
- columns = math.ceil(math.sqrt(self.nr_sockets))
- rows = math.ceil(self.nr_sockets / columns)
- box = gtk.HBox()
- else:
- box = vbox
-
- column = 1
- for socket_id in socket_ids:
- frame = cpu_socket_frame(socket_id,
- self.cpus.sockets[socket_id],
- self)
- box.pack_start(frame, False, False)
- self.socket_frames[socket_id] = frame
- if self.nr_sockets > 1:
- if column == columns:
- vbox.pack_start(box, True, True)
- box = gtk.HBox()
- column = 1
- else:
- column += 1
-
- window.show_all()
-
- self.cpus_filtered = cpus_filtered
- self.refresh()
-
- self.previous_pid_affinities = None
- self.previous_irq_affinities = None
-
- req = frame.size_request()
- # FIXME: what is the slack we have
- # to add to every row and column?
- width = req[0] + 16
- height = req[1] + 20
- if self.nr_sockets > 1:
- width *= columns
- height *= rows
- vpaned.set_position(int(height))
- hpaned.set_position(int(width))
-
- self.timer = gobject.timeout_add(3000, self.refresh)
-
- def isolate_cpus(self, cpus):
- self.previous_pid_affinities, \
- self.previous_irq_affinities = tuna.isolate_cpus(cpus, self.cpus.nr_cpus)
-
- if self.previous_pid_affinities:
- self.procview.refresh()
-
- if self.previous_irq_affinities:
- self.irqview.refresh()
-
- def include_cpus(self, cpus):
- self.previous_pid_affinities, \
- self.previous_irq_affinities = tuna.include_cpus(cpus, self.cpus.nr_cpus)
-
- if self.previous_pid_affinities:
- self.procview.refresh()
-
- if self.previous_irq_affinities:
- self.irqview.refresh()
-
- def restore_cpu(self):
- if not (self.previous_pid_affinities or \
- self.previous_irq_affinities):
- return
- affinities = self.previous_pid_affinities
- for pid in affinities.keys():
- try:
- schedutils.set_affinity(pid, affinities[pid])
- except:
- pass
-
- affinities = self.previous_irq_affinities
- for irq in affinities.keys():
- tuna.set_irq_affinity(int(irq),
- procfs.hexbitmask(affinities[irq],
- self.cpus.nr_cpus))
-
- self.previous_pid_affinities = None
- self.previous_irq_affinities = None
-
- def toggle_mask_cpu(self, cpu, enabled):
- if enabled:
- if cpu in self.cpus_filtered:
- self.cpus_filtered.remove(cpu)
- else:
- if cpu not in self.cpus_filtered:
- self.cpus_filtered.append(cpu)
-
- self.procview.toggle_mask_cpu(cpu, enabled)
- self.irqview.toggle_mask_cpu(cpu, enabled)
-
- def refresh(self):
- self.cpustats.reload()
- for frame in self.socket_frames.keys():
- self.socket_frames[frame].refresh()
- return True
-
def on_affinity_text_changed(self):
new_affinity_text = self.affinity.get_text().strip()
if self.affinity_text != new_affinity_text:
@@ -626,7 +274,7 @@ class irqview:
# Allow enable drag and drop of rows
self.treeview.enable_model_drag_source(gtk.gdk.BUTTON1_MASK,
- DND_TARGETS,
+ gui.DND_TARGETS,
gtk.gdk.ACTION_DEFAULT | gtk.gdk.ACTION_MOVE)
self.treeview.connect("drag_data_get", self.on_drag_data_get_data)
self.renderer = gtk.CellRendererText()
@@ -1009,7 +657,7 @@ class procview:
# Allow enable drag and drop of rows
self.treeview.enable_model_drag_source(gtk.gdk.BUTTON1_MASK,
- DND_TARGETS,
+ gui.DND_TARGETS,
gtk.gdk.ACTION_DEFAULT | gtk.gdk.ACTION_MOVE)
self.treeview.connect("drag_data_get", self.on_drag_data_get_data)
try:
@@ -1375,7 +1023,7 @@ class procview:
self.cpus_filtered.remove(cpu)
self.show(True)
-class gui:
+class main_gui:
def __init__(self, show_kthreads = True, show_uthreads = True, cpus_filtered = []):
global tuna_glade