diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2008-09-15 17:26:00 -0300 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2008-09-15 17:26:00 -0300 |
commit | e7bdb86acddcb955c619a48276964b1acae12c36 (patch) | |
tree | 564fe4c0593114db4ee8f271a9d40db50a102af7 | |
parent | f1c92c8cad34b0e04031b3dcc1412c215f9c47b8 (diff) | |
parent | 51725ad1e9fe5987c726a84b5417018725e70df7 (diff) | |
download | tuna-e7bdb86acddcb955c619a48276964b1acae12c36.tar.gz |
Merge branch 'sockets'
-rwxr-xr-x | tuna-cmd.py | 23 | ||||
-rw-r--r-- | tuna/sysfs.py | 102 | ||||
-rwxr-xr-x | tuna/tuna.py | 32 | ||||
-rw-r--r-- | tuna/tuna_gui.glade | 18 | ||||
-rw-r--r-- | tuna/tuna_gui.py | 308 |
5 files changed, 360 insertions, 123 deletions
diff --git a/tuna-cmd.py b/tuna-cmd.py index d5dea91..b90e2de 100755 --- a/tuna-cmd.py +++ b/tuna-cmd.py @@ -14,7 +14,7 @@ # General Public License for more details. import getopt, procfs, sys -from tuna import tuna +from tuna import tuna, sysfs try: from sets import Set as set @@ -40,6 +40,7 @@ def usage(): -m, --move move selected entities to CPU-LIST -p, --priority=[POLICY]:RTPRIO set thread scheduler POLICY and RTPRIO -s, --save=FILENAME save kthreads sched tunables to FILENAME + -S, --sockets=CPU-SOCKET-LIST CPU-SOCKET-LIST affected by commands -t, --threads=THREAD-LIST THREAD-LIST affected by commands -U, --no_uthreads Operations will not affect user threads -W, --what_is Provides help about selected entities''' @@ -77,13 +78,13 @@ def save(cpus, threads, filename): def main(): try: opts, args = getopt.getopt(sys.argv[1:], - "c:CfghiIKmp:s:t:UW", + "c:CfghiIKmp:s:S:t:UW", ("cpus=", "affect_children", "filter", "gui", "help", "isolate", "include", "no_kthreads", "move", "priority", - "save=", "threads=", + "save=", "sockets=", "threads=", "no_uthreads", "what_is")) except getopt.GetoptError, err: usage() @@ -121,8 +122,7 @@ def main(): if not cpus: print "tuna: --include requires a cpu list!" sys.exit(2) - for cpu in cpus: - tuna.include_cpu(cpu, get_nr_cpus()) + tuna.include_cpus(cpus, get_nr_cpus()) elif o in ("-p", "--priority"): tuna.threads_set_priority(threads, a, affect_children) elif o in ("-m", "--move"): @@ -135,6 +135,19 @@ def main(): tuna.move_threads_to_cpu(cpus, threads) elif o in ("-s", "--save"): save(cpus, threads, a) + elif o in ("-S", "--sockets"): + sockets = map(lambda socket: socket, a.split(",")) + if not cpus: + cpus = [] + cpu_info = sysfs.cpus() + for socket in sockets: + if not cpu_info.sockets.has_key(socket): + print "tuna: invalid socket %s, sockets available: %s" % \ + (socket, + ", ".join(cpu_info.sockets.keys())) + sys.exit(2) + cpus += [ int(cpu.name[3:]) for cpu in cpu_info.sockets[socket] ] + cpus.sort() elif o in ("-K", "--no_kthreads"): kthreads = False elif o in ("-U", "--no_uthreads"): diff --git a/tuna/sysfs.py b/tuna/sysfs.py new file mode 100644 index 0000000..bfb84b4 --- /dev/null +++ b/tuna/sysfs.py @@ -0,0 +1,102 @@ +#! /usr/bin/python +# -*- python -*- +# -*- coding: utf-8 -*- + +import os + +class cpu: + def __init__(self, basedir, name): + self.name = name + self.dir = "%s/%s" % (basedir, name) + self.reload() + + def readfile(self, name): + try: + f = open("%s/%s" % (self.dir, name)) + value = f.readline().strip() + f.close() + except: + raise + return value + + def reload_online(self): + self.online = True + try: + self.online = self.readfile("online") == "1" + except: + # boot CPU, usually cpu0, can't be brought offline, so + # lacks the file and non root users can't read. In both + # cases assume CPU is online. + pass + + def reload(self): + self.reload_online() + if self.online: + self.physical_package_id = self.readfile("topology/physical_package_id") + else: + self.physical_package_id = None + + def set_online(self, online = True): + try: + f = open("%s/online" % self.dir, "w") + f.write("%d\n" % (online and 1 or 0)) + f.close() + except: + pass + + self.reload_online() + return online == self.online + +class cpus: + def __init__(self, basedir = "/sys/devices/system/cpu"): + self.basedir = basedir + self.cpus = {} + self.sockets = {} + self.reload() + self.nr_cpus = len(self.cpus) + + def __getitem__(self, key): + return self.cpus[key] + + def keys(self): + return self.cpus.keys() + + def has_key(self, key): + return self.cpus.has_key(key) + + def reload(self): + sockets_to_sort = [] + for name in os.listdir(self.basedir): + if name[:3] != "cpu" or not name[3].isdigit(): + continue + + if name in self.cpus: + self.cpus[name].reload(self.basedir) + else: + c = cpu(self.basedir, name) + self.cpus[name] = c + socket = c.physical_package_id + if socket in self.sockets: + self.sockets[socket].insert(0, c) + else: + self.sockets[socket] = [ c, ] + + sockets_to_sort.append(socket) + + for socket in sockets_to_sort: + self.sockets[socket].sort() + +if __name__ == '__main__': + import sys + + cpus = cpus() + + for socket in cpus.sockets.keys(): + print "Socket %s" % socket + for c in cpus.sockets[socket]: + print " %s" % c.name + print " online: %s" % c.online + c.set_online(False) + print " online: %s" % c.online + c.set_online() + print " online: %s" % c.online diff --git a/tuna/tuna.py b/tuna/tuna.py index 0c7a53c..6de6ec8 100755 --- a/tuna/tuna.py +++ b/tuna/tuna.py @@ -142,20 +142,22 @@ def list_to_cpustring(l): prev = i return ",".join(strings) -def move_threads_to_cpu(new_affinity, pid_list): +def move_threads_to_cpu(new_affinity, pid_list, set_affinity_warning = None): changed = False ps = procfs.pidstats() for pid in pid_list: try: curr_affinity = schedutils.get_affinity(pid) - if curr_affinity != new_affinity: + if set(curr_affinity) != set(new_affinity): schedutils.set_affinity(pid, new_affinity) curr_affinity = schedutils.get_affinity(pid) - if curr_affinity == new_affinity: + if set(curr_affinity) == set(new_affinity): changed = True - else: + elif set_affinity_warning: set_affinity_warning(pid, new_affinity) + else: + print "move_threads_to_cpu: could not change pid %d affinity to %s" % (pid, new_affinity) # See if this is the thread group leader if not ps.has_key(pid): @@ -164,13 +166,15 @@ def move_threads_to_cpu(new_affinity, pid_list): threads = procfs.pidstats("/proc/%d/task" % pid) for tid in threads.keys(): curr_affinity = schedutils.get_affinity(tid) - if curr_affinity != new_affinity: + if set(curr_affinity) != set(new_affinity): schedutils.set_affinity(tid, new_affinity) curr_affinity = schedutils.get_affinity(tid) - if curr_affinity == new_affinity: + if set(curr_affinity) == set(new_affinity): changed = True - else: + elif set_affinity_warning: set_affinity_warning(tid, new_affinity) + else: + print "move_threads_to_cpu: could not change pid %d affinity to %s" % (pid, new_affinity) except SystemError: # process died continue @@ -228,7 +232,7 @@ def isolate_cpus(cpus, nr_cpus): return (previous_pid_affinities, previous_irq_affinities) -def include_cpu(cpu, nr_cpus): +def include_cpus(cpus, nr_cpus): ps = procfs.pidstats() ps.reload_threads() previous_pid_affinities = {} @@ -236,9 +240,9 @@ def include_cpu(cpu, nr_cpus): if iskthread(pid): continue affinity = schedutils.get_affinity(pid) - if cpu not in affinity: + if set(affinity).intersection(set(cpus)) != set(cpus): previous_pid_affinities[pid] = copy.copy(affinity) - affinity.append(cpu) + affinity = list(set(affinity + cpus)) schedutils.set_affinity(pid, affinity) if not ps[pid].has_key("threads"): @@ -248,9 +252,9 @@ def include_cpu(cpu, nr_cpus): if iskthread(tid): continue affinity = schedutils.get_affinity(tid) - if cpu not in affinity: + if set(affinity).intersection(set(cpus)) != set(cpus): previous_pid_affinities[tid] = copy.copy(affinity) - affinity.append(cpu) + affinity = list(set(affinity + cpus)) schedutils.set_affinity(tid, affinity) del ps @@ -263,9 +267,9 @@ def include_cpu(cpu, nr_cpus): if not irqs[irq].has_key("affinity"): continue affinity = irqs[irq]["affinity"] - if cpu not in affinity: + if set(affinity).intersection(set(cpus)) != set(cpus): previous_irq_affinities[irq] = copy.copy(affinity) - affinity.append(cpu) + affinity = list(set(affinity + cpus)) set_irq_affinity(int(irq), procfs.hexbitmask(affinity, nr_cpus)) diff --git a/tuna/tuna_gui.glade b/tuna/tuna_gui.glade index 97622a0..d1fd146 100644 --- a/tuna/tuna_gui.glade +++ b/tuna/tuna_gui.glade @@ -26,19 +26,23 @@ <property name="border_width">3</property> <property name="position">200</property> <child> - <widget class="GtkScrolledWindow" id="scrolledwindow1"> + <widget class="GtkScrolledWindow" id="cpuview"> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="hscrollbar_policy">GTK_POLICY_NEVER</property> + <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property> <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property> <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property> <child> - <widget class="GtkTreeView" id="cpuview"> + <widget class="GtkViewport" id="viewport2"> <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="border_width">2</property> - <property name="enable_search">False</property> - <signal name="button_press_event" handler="on_cpuview_button_press_event"/> + <child> + <widget class="GtkVBox" id="cpuview_box"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="border_width">2</property> + <signal name="button_press_event" handler="on_cpuview_button_press_event"/> + </widget> + </child> </widget> </child> </widget> diff --git a/tuna/tuna_gui.py b/tuna/tuna_gui.py index 947da71..dbc8b3f 100644 --- a/tuna/tuna_gui.py +++ b/tuna/tuna_gui.py @@ -6,6 +6,7 @@ import pygtk pygtk.require("2.0") import copy, ethtool, gtk, gobject, os, pango, procfs, re, schedutils, sys, tuna +import sysfs, math import gtk.glade try: @@ -37,22 +38,16 @@ def set_affinity_warning(tid, affinity): dialog.run() dialog.destroy() -def drop_handler_move_threads_to_cpu(cpu, data): +def drop_handler_move_threads_to_cpu(new_affinity, data): pid_list = [ int(pid) for pid in data.split(",") ] - if cpu >= 0: - new_affinity = [ cpu, ] - else: - new_affinity = range(-cpu) - tuna.move_threads_to_cpu(new_affinity, pid_list) + return tuna.move_threads_to_cpu(new_affinity, pid_list, + set_affinity_warning) -def drop_handler_move_irqs_to_cpu(cpu, data): +def drop_handler_move_irqs_to_cpu(cpus, data): irq_list = [ int(irq) for irq in data.split(",") ] - if cpu >= 0: - new_affinity = [ 1 << cpu, ] - else: - cpu = -cpu - new_affinity = [ (1 << cpu) - 1, ] + 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) @@ -85,26 +80,28 @@ def generate_list_store_columns_with_attr(columns): for column in columns: yield gobject.TYPE_UINT -class cpuview: +class cpu_socket_frame(gtk.Frame): ( COL_FILTER, COL_CPU, COL_USAGE ) = range(3) - def __init__(self, treeview, procview, irqview, cpus_filtered): - self.cpustats = procfs.cpusstats() - self.procview = procview - self.irqview = irqview - self.treeview = treeview + def __init__(self, socket, cpus, creator): + + gtk.Frame.__init__(self, "Socket %s" % socket) + + 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.set_model(self.list_store) - self.nr_cpus = len(self.cpustats) - 1 - model = self.treeview.get_model() + self.treeview = gtk.TreeView(self.list_store) # Filter column renderer = gtk.CellRendererToggle() - renderer.connect('toggled', self.filter_toggled, model) + renderer.connect('toggled', self.filter_toggled, self.list_store) column = gtk.TreeViewColumn('Filter', renderer, active = self.COL_FILTER) self.treeview.append_column(column) @@ -123,19 +120,71 @@ class cpuview: 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.timer = gobject.timeout_add(3000, self.refresh) + self.drop_handlers = { "pid": (drop_handler_move_threads_to_cpu, self.creator.procview), + "irq": (drop_handler_move_irqs_to_cpu, self.creator.irqview), } - self.drop_handlers = { "pid": (drop_handler_move_threads_to_cpu, self.procview), - "irq": (drop_handler_move_irqs_to_cpu, self.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) - self.previous_pid_affinities = None - self.previous_irq_affinities = None - self.cpus_filtered = cpus_filtered + 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) @@ -146,14 +195,8 @@ class cpuview: return row = self.list_store.get_iter(path) cpu = self.list_store.get_value(row, self.COL_CPU) - self.previous_pid_affinities, \ - self.previous_irq_affinities = tuna.isolate_cpus([cpu,], self.nr_cpus) - - if self.previous_pid_affinities: - self.procview.refresh() - if self.previous_irq_affinities: - self.irqview.refresh() + self.creator.isolate_cpus([cpu,]) def include_cpu(self, a): ret = self.treeview.get_path_at_pos(self.last_x, self.last_y) @@ -164,36 +207,26 @@ class cpuview: return row = self.list_store.get_iter(path) cpu = self.list_store.get_value(row, self.COL_CPU) - self.previous_pid_affinities, \ - self.previous_irq_affinities = tuna.include_cpu(cpu, self.nr_cpus) - if self.previous_pid_affinities: - self.procview.refresh() - - if self.previous_irq_affinities: - self.irqview.refresh() + self.creator.include_cpus([cpu,]) def restore_cpu(self, a): - 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.nr_cpus)) + self.creator.restore_cpu() - self.previous_pid_affinities = None - self.previous_irq_affinities = None + def isolate_cpu_socket(self, a): - def on_cpuview_button_press_event(self, treeview, event): + # 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 @@ -203,48 +236,34 @@ class cpuview: menu = gtk.Menu() include = gtk.MenuItem("I_nclude CPU") + include_socket = gtk.MenuItem("I_nclude CPU Socket") isolate = gtk.MenuItem("_Isolate CPU") + isolate_socket = gtk.MenuItem("_Isolate CPU Socket") restore = gtk.MenuItem("_Restore CPU") menu.add(include) + menu.add(include_socket) menu.add(isolate) + menu.add(isolate_socket) menu.add(restore) include.connect_object('activate', self.include_cpu, event) + include_socket.connect_object('activate', self.include_cpu_socket, event) isolate.connect_object('activate', self.isolate_cpu, event) - if not (self.previous_pid_affinities or \ - self.previous_irq_affinities): + 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() + include_socket.show() isolate.show() + isolate_socket.show() restore.show() menu.popup(None, None, None, event.button, event.time) - 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) - cpu = model.get_value(iter, self.COL_CPU) - else: - # Move to all CPUs - cpu = -self.nr_cpus - - if self.drop_handlers.has_key(source): - if self.drop_handlers[source][0](cpu, data): - self.drop_handlers[source][1].refresh() - else: - print "cpuview: unhandled drag source '%s'" % source - def filter_toggled(self, cell, path, model): # get toggled iter iter = model.get_iter((int(path),)) @@ -252,7 +271,110 @@ class cpuview: 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() + + nr_sockets = len(socket_ids) + if nr_sockets > 1: + columns = math.ceil(math.sqrt(nr_sockets)) + rows = math.ceil(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 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 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) @@ -263,19 +385,10 @@ class cpuview: self.procview.toggle_mask_cpu(cpu, enabled) self.irqview.toggle_mask_cpu(cpu, enabled) - # set new value - model.set(iter, self.COL_FILTER, enabled) - def refresh(self): - self.list_store.clear() self.cpustats.reload() - for cpunr in range(self.nr_cpus): - cpu = self.list_store.append() - usage = self.cpustats[cpunr + 1].usage - self.list_store.set(cpu, self.COL_FILTER, cpunr not in self.cpus_filtered, - self.COL_CPU, cpunr, - self.COL_USAGE, int(usage)) - self.treeview.show_all() + for frame in self.socket_frames.keys(): + self.socket_frames[frame].refresh() return True def on_affinity_text_changed(self): @@ -1258,13 +1371,14 @@ class gui: self.ps, show_kthreads, show_uthreads, cpus_filtered) self.irqview = irqview(self.wtree.get_widget("irqlist"), self.irqs, self.ps, cpus_filtered) - self.cpuview = cpuview(self.wtree.get_widget("cpuview"), + self.cpuview = cpuview(self.wtree.get_widget("vpaned1"), + self.wtree.get_widget("hpaned2"), + self.wtree.get_widget("cpuview"), self.procview, self.irqview, cpus_filtered) event_handlers = { "on_mainbig_window_delete_event" : self.on_mainbig_window_delete_event, "on_processlist_button_press_event" : self.procview.on_processlist_button_press_event, - "on_irqlist_button_press_event" : self.irqview.on_irqlist_button_press_event, - "on_cpuview_button_press_event" : self.cpuview.on_cpuview_button_press_event } + "on_irqlist_button_press_event" : self.irqview.on_irqlist_button_press_event } self.wtree.signal_autoconnect(event_handlers) self.ps.reload_threads() |