def __init__(self, treeview, irqs, ps, cpus_filtered, gladefile): self.is_root = os.getuid() == 0 self.irqs = irqs self.ps = ps self.treeview = treeview self.gladefile = gladefile self.has_threaded_irqs = tuna.has_threaded_irqs(ps) if not self.has_threaded_irqs: self.nr_columns = 4 (self.COL_NUM, self.COL_AFF, self.COL_EVENTS, self.COL_USERS) = range(self.nr_columns) self.columns = (gui.list_store_column(_("IRQ")), gui.list_store_column(_("Affinity"), gobject.TYPE_STRING), gui.list_store_column(_("Events")), gui.list_store_column(_("Users"), gobject.TYPE_STRING)) self.list_store = gtk.ListStore( *gui.generate_list_store_columns_with_attr(self.columns)) # Allow selecting multiple rows selection = treeview.get_selection() selection.set_mode(gtk.SELECTION_MULTIPLE) # Allow enable drag and drop of rows self.treeview.enable_model_drag_source( gtk.gdk.BUTTON1_MASK, 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() for col in range(self.nr_columns): column = gtk.TreeViewColumn(self.columns[col].name, self.renderer, text=col) column.set_sort_column_id(col) column.add_attribute(self.renderer, "weight", col + self.nr_columns) self.treeview.append_column(column) self.cpus_filtered = cpus_filtered self.refreshing = True self.treeview.set_model(self.list_store)
def __init__(self, treeview, irqs, ps, cpus_filtered, gladefile): self.is_root = os.getuid() == 0 self.irqs = irqs self.ps = ps self.treeview = treeview self.gladefile = gladefile self.has_threaded_irqs = tuna.has_threaded_irqs(ps) if not self.has_threaded_irqs: self.nr_columns = 4 ( self.COL_NUM, self.COL_AFF, self.COL_EVENTS, self.COL_USERS ) = range(self.nr_columns) self.columns = (gui.list_store_column(_("IRQ")), gui.list_store_column(_("Affinity"), gobject.TYPE_STRING), gui.list_store_column(_("Events")), gui.list_store_column(_("Users"), gobject.TYPE_STRING)) self.list_store = gtk.ListStore(*gui.generate_list_store_columns_with_attr(self.columns)) # Allow selecting multiple rows selection = treeview.get_selection() selection.set_mode(gtk.SELECTION_MULTIPLE) # Allow enable drag and drop of rows self.treeview.enable_model_drag_source(gtk.gdk.BUTTON1_MASK, 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() for col in range(self.nr_columns): column = gtk.TreeViewColumn(self.columns[col].name, self.renderer, text = col) column.set_sort_column_id(col) column.add_attribute(self.renderer, "weight", col + self.nr_columns) self.treeview.append_column(column) self.cpus_filtered = cpus_filtered self.refreshing = True self.treeview.set_model(self.list_store)
def __init__(self, treeview, ps, show_kthreads, show_uthreads, cpus_filtered, gladefile): self.ps = ps self.treeview = treeview self.nr_cpus = procfs.cpuinfo().nr_cpus self.gladefile = gladefile self.evlist = None try: self.perf_init() except: # No perf, poll /proc baby, poll pass if not ps[1]["status"].has_key("voluntary_ctxt_switches"): self.nr_columns = 5 else: self.nr_columns = 7 try: if ps[1]["cgroups"]: self.nr_columns = self.nr_columns + 1 except: pass self.columns = (gui.list_store_column(_("PID")), gui.list_store_column(_("Policy"), gobject.TYPE_STRING), gui.list_store_column(_("Priority")), gui.list_store_column(_("Affinity"), gobject.TYPE_STRING)) if self.nr_columns == 5: (self.COL_PID, self.COL_POL, self.COL_PRI, self.COL_AFF, self.COL_CMDLINE) = range(self.nr_columns) self.columns = self.columns + (gui.list_store_column( _("Command Line"), gobject.TYPE_STRING)) elif self.nr_columns == 6: (self.COL_PID, self.COL_POL, self.COL_PRI, self.COL_AFF, self.COL_CGROUP, self.COL_CMDLINE) = range(self.nr_columns) self.columns = self.columns + ( gui.list_store_column(_("CGroup"), gobject.TYPE_STRING), gui.list_store_column(_("Command Line"), gobject.TYPE_STRING)) elif self.nr_columns == 7: (self.COL_PID, self.COL_POL, self.COL_PRI, self.COL_AFF, self.COL_VOLCTXT, self.NONVOLCTXT, self.COL_CMDLINE) = range(self.nr_columns) self.columns = self.columns + ( gui.list_store_column(_("VolCtxtSwitch"), gobject.TYPE_UINT), gui.list_store_column(_("NonVolCtxtSwitch"), gobject.TYPE_UINT), gui.list_store_column(_("Command Line"), gobject.TYPE_STRING)) elif self.nr_columns == 8: (self.COL_PID, self.COL_POL, self.COL_PRI, self.COL_AFF, self.COL_VOLCTXT, self.COL_NONVOLCTXT, self.COL_CGROUP, self.COL_CMDLINE) = range(self.nr_columns) self.columns = self.columns + ( gui.list_store_column(_("VolCtxtSwitch"), gobject.TYPE_UINT), gui.list_store_column(_("NonVolCtxtSwitch"), gobject.TYPE_UINT), gui.list_store_column(_("CGroup"), gobject.TYPE_STRING), gui.list_store_column(_("Command Line"), gobject.TYPE_STRING)) self.tree_store = gtk.TreeStore( *gui.generate_list_store_columns_with_attr(self.columns)) self.treeview.set_model(self.tree_store) # Allow selecting multiple rows selection = treeview.get_selection() selection.set_mode(gtk.SELECTION_MULTIPLE) # Allow enable drag and drop of rows self.treeview.enable_model_drag_source( gtk.gdk.BUTTON1_MASK, gui.DND_TARGETS, gtk.gdk.ACTION_DEFAULT | gtk.gdk.ACTION_MOVE) self.treeview.connect("drag_data_get", self.on_drag_data_get_data) try: self.treeview.connect("query-tooltip", self.on_query_tooltip) except: # old versions of pygtk2+ doesn't have this signal pass self.renderer = gtk.CellRendererText() for col in range(self.nr_columns): column = gtk.TreeViewColumn(self.columns[col].name, self.renderer, text=col) column.add_attribute(self.renderer, "weight", col + self.nr_columns) column.set_sort_column_id(col) if (col == self.COL_CGROUP): column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED) column.set_fixed_width(130) try: self.treeview.set_tooltip_column(col) except: # old versions of pygtk2+ doesn't have this signal pass column.set_resizable(True) self.treeview.append_column(column) self.show_kthreads = show_kthreads self.show_uthreads = show_uthreads self.cpus_filtered = cpus_filtered self.refreshing = True
class procview: nr_columns = 8 (COL_PID, COL_POL, COL_PRI, COL_AFF, COL_VOLCTXT, COL_NONVOLCTXT, COL_CGROUP, COL_CMDLINE) = range(nr_columns) columns = (gui.list_store_column(_("PID")), gui.list_store_column(_("Policy"), gobject.TYPE_STRING), gui.list_store_column(_("Priority")), gui.list_store_column(_("Affinity"), gobject.TYPE_STRING), gui.list_store_column(_("VolCtxtSwitch"), gobject.TYPE_UINT), gui.list_store_column(_("NonVolCtxtSwitch"), gobject.TYPE_UINT), gui.list_store_column(_("CGroup"), gobject.TYPE_STRING), gui.list_store_column(_("Command Line"), gobject.TYPE_STRING)) def __init__(self, treeview, ps, show_kthreads, show_uthreads, cpus_filtered, gladefile): self.ps = ps self.treeview = treeview self.nr_cpus = procfs.cpuinfo().nr_cpus self.gladefile = gladefile self.evlist = None try: self.perf_init() except: # No perf, poll /proc baby, poll pass if not ps[1]["status"].has_key("voluntary_ctxt_switches"): self.nr_columns = 5 else: self.nr_columns = 7 try: if ps[1]["cgroups"]: self.nr_columns = self.nr_columns + 1 except: pass self.columns = (gui.list_store_column(_("PID")), gui.list_store_column(_("Policy"), gobject.TYPE_STRING), gui.list_store_column(_("Priority")), gui.list_store_column(_("Affinity"), gobject.TYPE_STRING)) if self.nr_columns == 5: (self.COL_PID, self.COL_POL, self.COL_PRI, self.COL_AFF, self.COL_CMDLINE) = range(self.nr_columns) self.columns = self.columns + (gui.list_store_column( _("Command Line"), gobject.TYPE_STRING)) elif self.nr_columns == 6: (self.COL_PID, self.COL_POL, self.COL_PRI, self.COL_AFF, self.COL_CGROUP, self.COL_CMDLINE) = range(self.nr_columns) self.columns = self.columns + ( gui.list_store_column(_("CGroup"), gobject.TYPE_STRING), gui.list_store_column(_("Command Line"), gobject.TYPE_STRING)) elif self.nr_columns == 7: (self.COL_PID, self.COL_POL, self.COL_PRI, self.COL_AFF, self.COL_VOLCTXT, self.NONVOLCTXT, self.COL_CMDLINE) = range(self.nr_columns) self.columns = self.columns + ( gui.list_store_column(_("VolCtxtSwitch"), gobject.TYPE_UINT), gui.list_store_column(_("NonVolCtxtSwitch"), gobject.TYPE_UINT), gui.list_store_column(_("Command Line"), gobject.TYPE_STRING)) elif self.nr_columns == 8: (self.COL_PID, self.COL_POL, self.COL_PRI, self.COL_AFF, self.COL_VOLCTXT, self.COL_NONVOLCTXT, self.COL_CGROUP, self.COL_CMDLINE) = range(self.nr_columns) self.columns = self.columns + ( gui.list_store_column(_("VolCtxtSwitch"), gobject.TYPE_UINT), gui.list_store_column(_("NonVolCtxtSwitch"), gobject.TYPE_UINT), gui.list_store_column(_("CGroup"), gobject.TYPE_STRING), gui.list_store_column(_("Command Line"), gobject.TYPE_STRING)) self.tree_store = gtk.TreeStore( *gui.generate_list_store_columns_with_attr(self.columns)) self.treeview.set_model(self.tree_store) # Allow selecting multiple rows selection = treeview.get_selection() selection.set_mode(gtk.SELECTION_MULTIPLE) # Allow enable drag and drop of rows self.treeview.enable_model_drag_source( gtk.gdk.BUTTON1_MASK, gui.DND_TARGETS, gtk.gdk.ACTION_DEFAULT | gtk.gdk.ACTION_MOVE) self.treeview.connect("drag_data_get", self.on_drag_data_get_data) try: self.treeview.connect("query-tooltip", self.on_query_tooltip) except: # old versions of pygtk2+ doesn't have this signal pass self.renderer = gtk.CellRendererText() for col in range(self.nr_columns): column = gtk.TreeViewColumn(self.columns[col].name, self.renderer, text=col) column.add_attribute(self.renderer, "weight", col + self.nr_columns) column.set_sort_column_id(col) if (col == self.COL_CGROUP): column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED) column.set_fixed_width(130) try: self.treeview.set_tooltip_column(col) except: # old versions of pygtk2+ doesn't have this signal pass column.set_resizable(True) self.treeview.append_column(column) self.show_kthreads = show_kthreads self.show_uthreads = show_uthreads self.cpus_filtered = cpus_filtered self.refreshing = True def perf_process_events(self, source, condition): had_events = True while had_events: had_events = False for cpu in self.cpu_map: event = self.evlist.read_on_cpu(cpu) if event: had_events = True if event.type == perf.RECORD_FORK: if event.pid == event.tid: try: self.ps.processes[event.pid] = procfs.process( event.pid) except: # short lived thread pass else: try: self.ps.processes[event.pid].threads.processes[ event.tid] = procfs.process(event.tid) except AttributeError: self.ps.processes[ event.pid].threads = procfs.pidstats( "/proc/%d/task/" % event.pid) elif event.type == perf.RECORD_EXIT: del self.ps[int(event.tid)] elif event.type == perf.RECORD_SAMPLE: tid = event.sample_tid if self.perf_counter.has_key(tid): self.perf_counter[tid] += event.sample_period else: self.perf_counter[tid] = event.sample_period self.show() return True def perf_init(self): self.cpu_map = perf.cpu_map() self.thread_map = perf.thread_map() self.evsel_cycles = perf.evsel(task=1, comm=1, wakeup_events=1, watermark=1, sample_type=perf.SAMPLE_CPU | perf.SAMPLE_TID) self.evsel_cycles.open(cpus=self.cpu_map, threads=self.thread_map) self.evlist = perf.evlist(self.cpu_map, self.thread_map) self.evlist.add(self.evsel_cycles) self.evlist.mmap() self.pollfd = self.evlist.get_pollfd() for f in self.pollfd: gobject.io_add_watch(f, gtk.gdk.INPUT_READ, self.perf_process_events) self.perf_counter = {} def on_query_tooltip(self, treeview, x, y, keyboard_mode, tooltip): x, y = treeview.convert_widget_to_bin_window_coords(x, y) ret = treeview.get_path_at_pos(x, y) tooltip.set_text(None) if not ret: return True path, col, xpos, ypos = ret if not path: return True col_id = col.get_sort_column_id() if col_id != self.COL_CMDLINE: return True row = self.tree_store.get_iter(path) if not row: return True pid = int(self.tree_store.get_value(row, self.COL_PID)) if not tuna.iskthread(pid): return True cmdline = self.tree_store.get_value(row, self.COL_CMDLINE).split(' ')[0] help = tuna.kthread_help(cmdline) tooltip.set_markup("<b>%s %d(%s)</b>\n%s" % \ (_("Kernel Thread"), pid, cmdline, _(help))) return True def foreach_selected_cb(self, model, path, iter, pid_list): pid = model.get_value(iter, self.COL_PID) pid_list.append(str(pid)) def on_drag_data_get_data(self, treeview, context, selection, target_id, etime): treeselection = treeview.get_selection() pid_list = [] treeselection.selected_foreach(self.foreach_selected_cb, pid_list) selection.set(selection.target, 8, "pid:" + ",".join(pid_list)) def set_thread_columns(self, iter, tid, thread_info): new_value = [None] * self.nr_columns new_value[self.COL_PRI] = int(thread_info["stat"]["rt_priority"]) new_value[self.COL_POL] = schedutils.schedstr( schedutils.get_scheduler(tid))[6:] thread_affinity_list = schedutils.get_affinity(tid) new_value[self.COL_PID] = tid new_value[self.COL_AFF] = tuna.list_to_cpustring(thread_affinity_list) try: new_value[self.COL_VOLCTXT] = int( thread_info["status"]["voluntary_ctxt_switches"]) new_value[self.COL_NONVOLCTXT] = int( thread_info["status"]["nonvoluntary_ctxt_switches"]) new_value[self.COL_CGROUP] = thread_info["cgroups"] except: pass new_value[self.COL_CMDLINE] = procfs.process_cmdline(thread_info) gui.set_store_columns(self.tree_store, iter, new_value) def show(self, force_refresh=False): # Start with the first row, if there is one, on the # process list. If the first time update_rows will just # have everything in new_tids and append_new_tids will # create the rows. if not self.refreshing and not force_refresh: return row = self.tree_store.get_iter_first() self.update_rows(self.ps, row, None) self.treeview.show_all() def update_rows(self, threads, row, parent_row): new_tids = threads.keys() previous_row = None while row: tid = self.tree_store.get_value(row, self.COL_PID) if previous_row: previous_tid = self.tree_store.get_value( previous_row, self.COL_PID) if previous_tid == tid: # print "WARNING: tree_store dup %d, fixing..." % tid self.tree_store.remove(previous_row) if not threads.has_key(tid): if self.tree_store.remove(row): # removed and now row is the next one continue # removed and its the last one break else: try: new_tids.remove(tid) except: # FIXME: understand in what situation this # can happen, seems harmless from visual # inspection. pass if tuna.thread_filtered(tid, self.cpus_filtered, self.show_kthreads, self.show_uthreads): if self.tree_store.remove(row): # removed and now row is the next one continue # removed and its the last one break else: try: self.set_thread_columns(row, tid, threads[tid]) if threads[tid].has_key("threads"): children = threads[tid]["threads"] else: children = {} child_row = self.tree_store.iter_children(row) self.update_rows(children, child_row, row) except: # thread doesn't exists anymore if self.tree_store.remove(row): # removed and now row is the next one continue # removed and its the last one break previous_row = row row = self.tree_store.iter_next(row) new_tids.sort() self.append_new_tids(parent_row, threads, new_tids) def append_new_tids(self, parent_row, threads, tid_list): for tid in tid_list: if tuna.thread_filtered(tid, self.cpus_filtered, self.show_kthreads, self.show_uthreads): continue row = self.tree_store.append(parent_row) try: self.set_thread_columns(row, tid, threads[tid]) except: # Thread doesn't exists anymore self.tree_store.remove(row) continue if threads[tid].has_key("threads"): children = threads[tid]["threads"] children_list = children.keys() children_list.sort() for child in children_list: child_row = self.tree_store.append(row) try: self.set_thread_columns(child_row, child, children[child]) except: # Thread doesn't exists anymore self.tree_store.remove(child_row) def refresh(self): self.ps.reload() self.ps.reload_threads() self.show(True) def edit_attributes(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.tree_store.get_iter(path) pid = self.tree_store.get_value(row, self.COL_PID) if self.ps.has_key(pid): pid_info = self.ps[pid] else: parent = self.tree_store.iter_parent(row) ppid = self.tree_store.get_value(parent, self.COL_PID) pid_info = self.ps[ppid].threads[pid] dialog = process_druid(self.ps, pid, pid_info, self.nr_cpus, self.gladefile) if dialog.run(): self.refresh() def kthreads_view_toggled(self, a): self.show_kthreads = not self.show_kthreads self.show(True) def uthreads_view_toggled(self, a): self.show_uthreads = not self.show_uthreads self.show(True) def help_dialog(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.tree_store.get_iter(path) pid = self.tree_store.get_value(row, self.COL_PID) if not self.ps.has_key(pid): return cmdline = self.tree_store.get_value(row, self.COL_CMDLINE) help, title = tuna.kthread_help_plain_text(pid, cmdline) dialog = gtk.MessageDialog( None, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, _(help)) dialog.set_title(title) ret = dialog.run() dialog.destroy() def refresh_toggle(self, a): self.refreshing = not self.refreshing def save_kthreads_tunings(self, a): dialog = gtk.FileChooserDialog(_("Save As"), None, gtk.FILE_CHOOSER_ACTION_SAVE, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OK, gtk.RESPONSE_OK)) dialog.set_default_response(gtk.RESPONSE_OK) try: dialog.set_do_overwrite_confirmation(True) except: pass filter = gtk.FileFilter() filter.set_name("rtctl config files") filter.add_pattern("*.rtctl") filter.add_pattern("*.tuna") filter.add_pattern("*rtgroup*") dialog.add_filter(filter) filter = gtk.FileFilter() filter.set_name("All files") filter.add_pattern("*") dialog.add_filter(filter) response = dialog.run() filename = dialog.get_filename() dialog.destroy() if response != gtk.RESPONSE_OK: return self.refresh() kthreads = tuna.get_kthread_sched_tunings(self.ps) tuna.generate_rtgroups(filename, kthreads, self.nr_cpus) if filename != "/etc/rtgroups": dialog = gtk.MessageDialog( None, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_INFO, gtk.BUTTONS_YES_NO, "Kernel thread tunings saved!\n\n" "Now you can use it with rtctl:\n\n" "rtctl --file %s reset\n\n" "If you want the changes to be in " "effect every time you boot the system " "please move %s to /etc/rtgroups\n\n" "Do you want to do that now?" % (filename, filename)) response = dialog.run() dialog.destroy() if response == gtk.RESPONSE_YES: filename = "/etc/rtgroups" tuna.generate_rtgroups(filename, kthreads, self.nr_cpus) dialog = gtk.MessageDialog( None, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, _("Kernel thread tunings saved to %s!") % filename) dialog.run() dialog.destroy() def on_processlist_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() setattr = gtk.MenuItem(_("_Set process attributes")) if self.refreshing: refresh = gtk.MenuItem(_("Sto_p refreshing the process list")) else: refresh = gtk.MenuItem(_("_Refresh the process list")) if self.show_kthreads: kthreads = gtk.MenuItem(_("_Hide kernel threads")) else: kthreads = gtk.MenuItem(_("_Show kernel threads")) if self.show_uthreads: uthreads = gtk.MenuItem(_("_Hide user threads")) else: uthreads = gtk.MenuItem(_("_Show user threads")) help = gtk.MenuItem(_("_What is this?")) save_kthreads_tunings = gtk.MenuItem(_("_Save kthreads tunings")) menu.add(save_kthreads_tunings) menu.add(setattr) menu.add(refresh) menu.add(kthreads) menu.add(uthreads) menu.add(help) save_kthreads_tunings.connect_object('activate', self.save_kthreads_tunings, event) setattr.connect_object('activate', self.edit_attributes, event) refresh.connect_object('activate', self.refresh_toggle, event) kthreads.connect_object('activate', self.kthreads_view_toggled, event) uthreads.connect_object('activate', self.uthreads_view_toggled, event) help.connect_object('activate', self.help_dialog, event) save_kthreads_tunings.show() setattr.show() refresh.show() kthreads.show() uthreads.show() help.show() menu.popup(None, None, None, event.button, event.time) def toggle_mask_cpu(self, cpu, enabled): if not enabled: if cpu not in self.cpus_filtered: self.cpus_filtered.append(cpu) self.show(True) else: if cpu in self.cpus_filtered: self.cpus_filtered.remove(cpu) self.show(True)
def __init__(self, treeview, ps, show_kthreads, show_uthreads, cpus_filtered, gladefile): self.ps = ps self.treeview = treeview self.nr_cpus = procfs.cpuinfo().nr_cpus self.gladefile = gladefile self.evlist = None try: self.perf_init() except: # No perf, poll /proc baby, poll pass if not ps[1]["status"].has_key("voluntary_ctxt_switches"): self.nr_columns = 5 else: self.nr_columns = 7 try: if ps[1]["cgroups"]: self.nr_columns = self.nr_columns + 1 except: pass self.columns = (gui.list_store_column(_("PID")), gui.list_store_column(_("Policy"), gobject.TYPE_STRING), gui.list_store_column(_("Priority")), gui.list_store_column(_("Affinity"), gobject.TYPE_STRING)) if self.nr_columns==5: ( self.COL_PID, self.COL_POL, self.COL_PRI, self.COL_AFF, self.COL_CMDLINE ) = range(self.nr_columns) self.columns = self.columns + (gui.list_store_column(_("Command Line"), gobject.TYPE_STRING)) elif self.nr_columns==6: ( self.COL_PID, self.COL_POL, self.COL_PRI, self.COL_AFF, self.COL_CGROUP, self.COL_CMDLINE ) = range(self.nr_columns) self.columns = self.columns + (gui.list_store_column(_("CGroup"), gobject.TYPE_STRING), gui.list_store_column(_("Command Line"), gobject.TYPE_STRING)) elif self.nr_columns==7: ( self.COL_PID, self.COL_POL, self.COL_PRI, self.COL_AFF, self.COL_VOLCTXT, self.NONVOLCTXT, self.COL_CMDLINE ) = range(self.nr_columns) self.columns = self.columns + (gui.list_store_column(_("VolCtxtSwitch"), gobject.TYPE_UINT), gui.list_store_column(_("NonVolCtxtSwitch"), gobject.TYPE_UINT), gui.list_store_column(_("Command Line"), gobject.TYPE_STRING)) elif self.nr_columns==8: ( self.COL_PID, self.COL_POL, self.COL_PRI, self.COL_AFF, self.COL_VOLCTXT, self.COL_NONVOLCTXT, self.COL_CGROUP, self.COL_CMDLINE ) = range(self.nr_columns) self.columns = self.columns + (gui.list_store_column(_("VolCtxtSwitch"), gobject.TYPE_UINT), gui.list_store_column(_("NonVolCtxtSwitch"), gobject.TYPE_UINT), gui.list_store_column(_("CGroup"), gobject.TYPE_STRING), gui.list_store_column(_("Command Line"), gobject.TYPE_STRING)) self.tree_store = gtk.TreeStore(*gui.generate_list_store_columns_with_attr(self.columns)) self.treeview.set_model(self.tree_store) # Allow selecting multiple rows selection = treeview.get_selection() selection.set_mode(gtk.SELECTION_MULTIPLE) # Allow enable drag and drop of rows self.treeview.enable_model_drag_source(gtk.gdk.BUTTON1_MASK, gui.DND_TARGETS, gtk.gdk.ACTION_DEFAULT | gtk.gdk.ACTION_MOVE) self.treeview.connect("drag_data_get", self.on_drag_data_get_data) try: self.treeview.connect("query-tooltip", self.on_query_tooltip) except: # old versions of pygtk2+ doesn't have this signal pass self.renderer = gtk.CellRendererText() for col in range(self.nr_columns): column = gtk.TreeViewColumn(self.columns[col].name, self.renderer, text = col) column.add_attribute(self.renderer, "weight", col + self.nr_columns) column.set_sort_column_id(col) if(col == self.COL_CGROUP): column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED) column.set_fixed_width(130) try: self.treeview.set_tooltip_column(col) except: # old versions of pygtk2+ doesn't have this signal pass column.set_resizable(True) self.treeview.append_column(column) self.show_kthreads = show_kthreads self.show_uthreads = show_uthreads self.cpus_filtered = cpus_filtered self.refreshing = True
class irqview: nr_columns = 7 (COL_NUM, COL_PID, COL_POL, COL_PRI, COL_AFF, COL_EVENTS, COL_USERS) = range(nr_columns) columns = (gui.list_store_column(_("IRQ")), gui.list_store_column(_("PID"), gobject.TYPE_INT), gui.list_store_column(_("Policy"), gobject.TYPE_STRING), gui.list_store_column(_("Priority"), gobject.TYPE_INT), gui.list_store_column(_("Affinity"), gobject.TYPE_STRING), gui.list_store_column(_("Events")), gui.list_store_column(_("Users"), gobject.TYPE_STRING)) def __init__(self, treeview, irqs, ps, cpus_filtered, gladefile): self.is_root = os.getuid() == 0 self.irqs = irqs self.ps = ps self.treeview = treeview self.gladefile = gladefile self.has_threaded_irqs = tuna.has_threaded_irqs(ps) if not self.has_threaded_irqs: self.nr_columns = 4 (self.COL_NUM, self.COL_AFF, self.COL_EVENTS, self.COL_USERS) = range(self.nr_columns) self.columns = (gui.list_store_column(_("IRQ")), gui.list_store_column(_("Affinity"), gobject.TYPE_STRING), gui.list_store_column(_("Events")), gui.list_store_column(_("Users"), gobject.TYPE_STRING)) self.list_store = gtk.ListStore( *gui.generate_list_store_columns_with_attr(self.columns)) # Allow selecting multiple rows selection = treeview.get_selection() selection.set_mode(gtk.SELECTION_MULTIPLE) # Allow enable drag and drop of rows self.treeview.enable_model_drag_source( gtk.gdk.BUTTON1_MASK, 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() for col in range(self.nr_columns): column = gtk.TreeViewColumn(self.columns[col].name, self.renderer, text=col) column.set_sort_column_id(col) column.add_attribute(self.renderer, "weight", col + self.nr_columns) self.treeview.append_column(column) self.cpus_filtered = cpus_filtered self.refreshing = True self.treeview.set_model(self.list_store) def foreach_selected_cb(self, model, path, iter, irq_list): irq = model.get_value(iter, self.COL_NUM) irq_list.append(str(irq)) def on_drag_data_get_data(self, treeview, context, selection, target_id, etime): treeselection = treeview.get_selection() irq_list = [] treeselection.selected_foreach(self.foreach_selected_cb, irq_list) selection.set(selection.target, 8, "irq:" + ",".join(irq_list)) def set_irq_columns(self, iter, irq, irq_info, nics): new_value = [None] * self.nr_columns users = tuna.get_irq_users(self.irqs, irq, nics) if self.has_threaded_irqs: irq_re = tuna.threaded_irq_re(irq) pids = self.ps.find_by_regex(irq_re) if pids: pid = pids[0] prio = int(self.ps[pid]["stat"]["rt_priority"]) sched = schedutils.schedstr(schedutils.get_scheduler(pid))[6:] else: sched = "" pid = -1 prio = -1 new_value[self.COL_PID] = pid new_value[self.COL_POL] = sched new_value[self.COL_PRI] = prio new_value[self.COL_NUM] = irq new_value[self.COL_AFF] = tuna.get_irq_affinity_text(self.irqs, irq) new_value[self.COL_EVENTS] = reduce(lambda a, b: a + b, irq_info["cpu"]) new_value[self.COL_USERS] = ",".join(users) gui.set_store_columns(self.list_store, iter, new_value) def show(self): new_irqs = [] for sirq in self.irqs.keys(): try: new_irqs.append(int(sirq)) except: continue nics = ethtool.get_active_devices() row = self.list_store.get_iter_first() while row: irq = self.list_store.get_value(row, self.COL_NUM) # IRQ was unregistered? I.e. driver unloaded? if not self.irqs.has_key(irq): if self.list_store.remove(row): # removed and row now its the next one continue # Was the last one break elif tuna.irq_filtered(irq, self.irqs, self.cpus_filtered, self.is_root): new_irqs.remove(irq) if self.list_store.remove(row): # removed and row now its the next one continue # Was the last one break else: try: new_irqs.remove(irq) irq_info = self.irqs[irq] self.set_irq_columns(row, irq, irq_info, nics) except: if self.list_store.remove(row): # removed and row now its the next one continue # Was the last one break row = self.list_store.iter_next(row) new_irqs.sort() for irq in new_irqs: if tuna.irq_filtered(irq, self.irqs, self.cpus_filtered, self.is_root): continue row = self.list_store.append() irq_info = self.irqs[irq] try: self.set_irq_columns(row, irq, irq_info, nics) except: self.list_store.remove(row) self.treeview.show_all() def refresh(self): if not self.refreshing: return self.irqs.reload() self.show() def refresh_toggle(self, unused): self.refreshing = not self.refreshing def edit_attributes(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) irq = self.list_store.get_value(row, self.COL_NUM) if not self.irqs.has_key(irq): return dialog = irq_druid(self.irqs, self.ps, irq, self.gladefile) if dialog.run(): self.refresh() def on_irqlist_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() setattr = gtk.MenuItem(_("_Set IRQ attributes")) if self.refreshing: refresh = gtk.MenuItem(_("Sto_p refreshing the IRQ list")) else: refresh = gtk.MenuItem(_("_Refresh the IRQ list")) menu.add(setattr) menu.add(refresh) setattr.connect_object('activate', self.edit_attributes, event) refresh.connect_object('activate', self.refresh_toggle, event) setattr.show() refresh.show() menu.popup(None, None, None, event.button, event.time) def toggle_mask_cpu(self, cpu, enabled): if not enabled: if cpu not in self.cpus_filtered: self.cpus_filtered.append(cpu) self.show() else: if cpu in self.cpus_filtered: self.cpus_filtered.remove(cpu) self.show()