From a7ac239303bf997546e36fb4f0a01fd46acb4d94 Mon Sep 17 00:00:00 2001 From: rim Date: Thu, 17 May 2018 02:35:45 +0300 Subject: [PATCH] Refactoring of task-manager.c --- src/app-manager.c | 15 +++++---------- src/main.c | 18 +++++++++--------- src/process-monitor.c | 4 ++-- src/process-statusbar.c | 4 ++-- src/process-tree-view.c | 16 ++++++---------- src/process-window.c | 10 +++++----- src/task-manager-bsd.c | 6 ++++-- src/task-manager-freebsd.c | 6 ++++-- src/task-manager-linux.c | 14 ++++++++------ src/task-manager-skel.c | 4 +++- src/task-manager-solaris.c | 10 ++++++---- src/task-manager.c | 323 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- src/task-manager.h | 9 +++++++++ 13 files changed, 179 insertions(+), 260 deletions(-) diff --git a/src/app-manager.c b/src/app-manager.c index a3609f4..a97725f 100644 --- a/src/app-manager.c +++ b/src/app-manager.c @@ -17,6 +17,7 @@ #include #include "app-manager.h" +#include "task-manager.h" @@ -78,9 +79,7 @@ xtm_app_manager_init (XtmAppManager *manager) apps_add_application (manager->apps, application); } -#if DEBUG - g_debug ("Initial applications: %d", manager->apps->len); -#endif + G_DEBUG_FMT ("Initial applications: %d", manager->apps->len); /* Connect signals */ g_signal_connect (screen, "application-opened", G_CALLBACK (application_opened), manager); @@ -111,7 +110,7 @@ apps_add_application (GArray *apps, WnckApplication *application) app.application = application; app.pid = pid; - g_snprintf (app.name, 1024, "%s", wnck_application_get_name (application)); + g_snprintf (app.name, sizeof(app.name), "%s", wnck_application_get_name (application)); app.icon = wnck_application_get_mini_icon (application); g_object_ref (app.icon); @@ -158,18 +157,14 @@ apps_lookup_pid (GArray *apps, gint pid) static void application_opened (WnckScreen *screen, WnckApplication *application, XtmAppManager *manager) { -#if DEBUG - g_debug ("Application opened %p %d", application, wnck_application_get_pid (application)); -#endif + G_DEBUG_FMT ("Application opened %p %d", application, wnck_application_get_pid (application)); apps_add_application (manager->apps, application); } static void application_closed (WnckScreen *screen, WnckApplication *application, XtmAppManager *manager) { -#if DEBUG - g_debug ("Application closed %p", application); -#endif + G_DEBUG_FMT ("Application closed %p", application); apps_remove_application (manager->apps, application); } diff --git a/src/main.c b/src/main.c index 1244bd6..3960f6d 100644 --- a/src/main.c +++ b/src/main.c @@ -26,7 +26,7 @@ static XtmSettings *settings; static GtkWidget *window; static GtkStatusIcon *status_icon; static XtmTaskManager *task_manager; -static gboolean timeout = 0; +static gboolean timeout = FALSE; static void status_icon_activated (void) @@ -93,25 +93,25 @@ init_timeout (void) xtm_task_manager_get_system_info (task_manager, &num_processes, &cpu, &memory_used, &memory_total, &swap_used, &swap_total); - memory_percent = (memory_total != 0) ? memory_used * 100 / (gdouble)memory_total : 0; - swap_percent = (swap_total != 0) ? swap_used * 100 / (gdouble)swap_total : 0; + memory_percent = (memory_total != 0) ? ((memory_used * 100.0f) / (float)memory_total) : 0.0f; + swap_percent = (swap_total != 0) ? ((swap_used * 100.0f) / (float)swap_total) : 0.0f; g_object_get (settings, "show-memory-in-xbytes", &show_memory_in_xbytes, NULL); if (show_memory_in_xbytes) { used = g_format_size_full(memory_used, G_FORMAT_SIZE_IEC_UNITS); total = g_format_size_full(memory_total, G_FORMAT_SIZE_IEC_UNITS); - g_snprintf (memory_info, 64,"%s / %s", used, total); + g_snprintf (memory_info, sizeof(memory_info), "%s / %s", used, total); g_free(used); g_free(total); used = g_format_size_full(swap_used, G_FORMAT_SIZE_IEC_UNITS); total = g_format_size_full(swap_total, G_FORMAT_SIZE_IEC_UNITS); - g_snprintf (swap_info, 64,"%s / %s", used, total); + g_snprintf (swap_info, sizeof(swap_info), "%s / %s", used, total); g_free(used); g_free(total); } else { - g_snprintf (memory_info, 64, "%.0f%%", memory_percent); - g_snprintf (swap_info, 64, "%.0f%%", swap_percent); + g_snprintf (memory_info, sizeof(memory_info), "%.0f%%", memory_percent); + g_snprintf (swap_info, sizeof(swap_info), "%.0f%%", swap_percent); } xtm_process_window_set_system_info (XTM_PROCESS_WINDOW (window), num_processes, cpu, memory_percent, memory_info, swap_percent, swap_info); @@ -122,15 +122,15 @@ init_timeout (void) if (gtk_status_icon_get_visible (status_icon)) { #if GTK_CHECK_VERSION (2,16,0) - g_snprintf (tooltip, 1024, + g_snprintf (tooltip, sizeof(tooltip), _("Processes: %u\n" "CPU: %.0f%%\n" "Memory: %s\n" "Swap: %s"), num_processes, cpu, memory_info, swap_info); gtk_status_icon_set_tooltip_markup (GTK_STATUS_ICON (status_icon), tooltip); #else - g_snprintf (tooltip, 1024, + g_snprintf (tooltip, sizeof(tooltip), _("Processes: %u\n" "CPU: %.0f%%\n" "Memory: %s\n" diff --git a/src/process-monitor.c b/src/process-monitor.c index 726b85d..4d48223 100644 --- a/src/process-monitor.c +++ b/src/process-monitor.c @@ -63,7 +63,7 @@ xtm_process_monitor_class_init (XtmProcessMonitorClass *klass) widget_class->expose_event = xtm_process_monitor_expose; #endif g_object_class_install_property (class, PROP_STEP_SIZE, - g_param_spec_float ("step-size", "StepSize", "Step size", 0.1, G_MAXFLOAT, 1, G_PARAM_CONSTRUCT|G_PARAM_READWRITE)); + g_param_spec_float ("step-size", "StepSize", "Step size", 0.1f, G_MAXFLOAT, 1, G_PARAM_CONSTRUCT|G_PARAM_READWRITE)); g_object_class_install_property (class, PROP_TYPE, g_param_spec_int ("type", "Type", "Type of graph to render", 0, G_MAXINT, 0, G_PARAM_READWRITE)); } @@ -267,7 +267,7 @@ void xtm_process_monitor_add_peak (XtmProcessMonitor *monitor, gfloat peak) { g_return_if_fail (XTM_IS_PROCESS_MONITOR (monitor)); - g_return_if_fail (peak >= 0.0 && peak <= 1.0); + g_return_if_fail (peak >= 0.0f && peak <= 1.0f); g_array_prepend_val (monitor->history, peak); if (monitor->history->len > 1) diff --git a/src/process-statusbar.c b/src/process-statusbar.c index 56e01e5..e1f069e 100644 --- a/src/process-statusbar.c +++ b/src/process-statusbar.c @@ -158,7 +158,7 @@ xtm_process_statusbar_set_property (GObject *object, guint property_id, const GV break; case PROP_MEMORY: - g_strlcpy(statusbar->memory, g_value_get_string (value), 64); + g_strlcpy(statusbar->memory, g_value_get_string (value), sizeof(statusbar->memory)); text = g_strdup_printf (_("Memory: %s"), statusbar->memory); gtk_label_set_text (GTK_LABEL (statusbar->label_memory), text); #if GTK_CHECK_VERSION(3, 0, 0) @@ -172,7 +172,7 @@ xtm_process_statusbar_set_property (GObject *object, guint property_id, const GV break; case PROP_SWAP: - g_strlcpy(statusbar->swap, g_value_get_string (value), 64); + g_strlcpy(statusbar->swap, g_value_get_string (value), sizeof(statusbar->swap)); text = g_strdup_printf (_("Swap: %s"), statusbar->swap); gtk_label_set_text (GTK_LABEL (statusbar->label_swap), text); g_free (text); diff --git a/src/process-tree-view.c b/src/process-tree-view.c index 748610a..ca4920f 100644 --- a/src/process-tree-view.c +++ b/src/process-tree-view.c @@ -345,7 +345,7 @@ save_columns_positions (XtmProcessTreeView *treeview) gchar columns_positions[COLUMNS_POSITIONS_STRLEN] = { 0 }; for (i = 0; i < N_COLUMNS; i++) - offset += g_snprintf (&columns_positions[offset], COLUMNS_POSITIONS_STRLEN - offset, "%d;", treeview->columns_positions[i]); + offset += g_snprintf (&columns_positions[offset], (sizeof(columns_positions) - offset), "%d;", treeview->columns_positions[i]); g_object_set (treeview->settings, "columns-positions", columns_positions, NULL); } @@ -397,6 +397,8 @@ cb_send_signal (GtkMenuItem *mi, gpointer user_data) GtkTreeSelection *selection; GtkWidget *treeview; treeview = g_object_get_data (G_OBJECT (mi), "treeview"); + if (NULL == treeview) + return; selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)); gtk_tree_selection_unselect_all (selection); } @@ -543,9 +545,7 @@ treeview_clicked (XtmProcessTreeView *treeview, GdkEventButton *event) gtk_tree_selection_select_path (selection, path); gtk_tree_path_free (path); -#if DEBUG - g_debug ("Found iter with pid %d", pid); -#endif + G_DEBUG_FMT ("Found iter with pid %d", pid); } popup_menu (treeview, pid, event->time, TRUE); @@ -601,9 +601,7 @@ column_clicked (GtkTreeViewColumn *column, XtmProcessTreeView *treeview) GtkSortType sort_type; gtk_tree_sortable_get_sort_column_id (GTK_TREE_SORTABLE (treeview->model), &sort_column_id, &sort_type); -#if DEBUG - g_debug ("Last sort column %d; sort type: %d", sort_column_id, sort_type); -#endif + G_DEBUG_FMT ("Last sort column %d; sort type: %d", sort_column_id, sort_type); if (treeview->sort_column != column) { @@ -617,9 +615,7 @@ column_clicked (GtkTreeViewColumn *column, XtmProcessTreeView *treeview) sort_type = (sort_type == GTK_SORT_ASCENDING) ? GTK_SORT_DESCENDING : GTK_SORT_ASCENDING; } -#if DEBUG - g_debug ("New sort column %d; sort type: %d", sort_column_id, sort_type); -#endif + G_DEBUG_FMT ("New sort column %d; sort type: %d", sort_column_id, sort_type); gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (treeview->model), sort_column_id, sort_type); gtk_tree_view_column_set_sort_order (column, sort_type); diff --git a/src/process-window.c b/src/process-window.c index 5bca7aa..6d7b825 100644 --- a/src/process-window.c +++ b/src/process-window.c @@ -567,13 +567,13 @@ xtm_process_window_set_system_info (XtmProcessWindow *window, guint num_processe g_object_set (window->statusbar, "num-processes", num_processes, "cpu", cpu, "memory", memory_str, "swap", swap_str, NULL); - xtm_process_monitor_add_peak (XTM_PROCESS_MONITOR (window->cpu_monitor), cpu / 100.0); - g_snprintf (value, 4, "%.0f", cpu); - g_snprintf (text, 100, _("CPU: %s%%"), value); + xtm_process_monitor_add_peak (XTM_PROCESS_MONITOR (window->cpu_monitor), cpu / 100.0f); + g_snprintf (value, sizeof(value), "%.0f", cpu); + g_snprintf (text, sizeof(text), _("CPU: %s%%"), value); gtk_widget_set_tooltip_text (window->cpu_monitor, text); - xtm_process_monitor_add_peak (XTM_PROCESS_MONITOR (window->mem_monitor), memory / 100.0); - g_snprintf (text, 100, _("Memory: %s"), memory_str); + xtm_process_monitor_add_peak (XTM_PROCESS_MONITOR (window->mem_monitor), memory / 100.0f); + g_snprintf (text, sizeof(text), _("Memory: %s"), memory_str); gtk_widget_set_tooltip_text (window->mem_monitor, text); } diff --git a/src/task-manager-bsd.c b/src/task-manager-bsd.c index 67fabbd..3c28759 100644 --- a/src/task-manager-bsd.c +++ b/src/task-manager-bsd.c @@ -151,6 +151,8 @@ gboolean get_task_list (GArray *task_list) } free(kp); + g_array_sort (task_list, task_pid_compare_fn); + return TRUE; } @@ -208,8 +210,8 @@ gboolean get_cpu_usage (gushort *cpu_count, gfloat *cpu_user, gfloat *cpu_system cur_system = cp_time[CP_SYS] + cp_time[CP_INTR]; cur_total = cur_user + cur_system + cp_time[CP_IDLE]; - *cpu_user = (old_total > 0) ? (cur_user - old_user) * 100 / (gdouble)(cur_total - old_total) : 0; - *cpu_system = (old_total > 0) ? (cur_system - old_system) * 100 / (gdouble)(cur_total - old_total) : 0; + *cpu_user = (old_total > 0) ? (((cur_user - old_user) * 100.0f) / (float)(cur_total - old_total)) : 0.0f; + *cpu_system = (old_total > 0) ? (((cur_system - old_system) * 100.0f) / (float)(cur_total - old_total)) : 0.0f; /* get #cpu */ size = sizeof(&cpu_count); diff --git a/src/task-manager-freebsd.c b/src/task-manager-freebsd.c index 84b8e5f..093de0e 100644 --- a/src/task-manager-freebsd.c +++ b/src/task-manager-freebsd.c @@ -109,8 +109,8 @@ get_cpu_usage (gushort *cpu_count, gfloat *cpu_user, gfloat *cpu_system) *cpu_user = *cpu_system = 0.0f; if (cp_total > cp_total_old) { - *cpu_user = (cp_user - cp_user_old) * 100.0f / (float)(cp_total - cp_total_old); - *cpu_system = (cp_system - cp_system_old) * 100.0f / (float)(cp_total - cp_total_old); + *cpu_user = (((cp_user - cp_user_old) * 100.0f) / (float)(cp_total - cp_total_old)); + *cpu_system = (((cp_system - cp_system_old) * 100.0f) / (float)(cp_total - cp_total_old)); } } @@ -256,6 +256,8 @@ get_task_list (GArray *task_list) kvm_close (kd); + g_array_sort (task_list, task_pid_compare_fn); + return TRUE; } diff --git a/src/task-manager-linux.c b/src/task-manager-linux.c index 2e26a70..68b0853 100644 --- a/src/task-manager-linux.c +++ b/src/task-manager-linux.c @@ -98,12 +98,12 @@ get_cpu_usage (gushort *cpu_count, gfloat *cpu_user, gfloat *cpu_system) jiffies_system = system; jiffies_total = jiffies_user + jiffies_system + idle; - *cpu_user = *cpu_system = 0.0; + *cpu_user = *cpu_system = 0.0f; if (jiffies_total > jiffies_total_old) { jiffies_total_delta = jiffies_total - jiffies_total_old; - *cpu_user = (jiffies_user - jiffies_user_old) * 100 / (gdouble)(jiffies_total_delta); - *cpu_system = (jiffies_system - jiffies_system_old) * 100 / (gdouble)(jiffies_total_delta); + *cpu_user = (((jiffies_user - jiffies_user_old) * 100.0f) / (float)jiffies_total_delta); + *cpu_system = (((jiffies_system - jiffies_system_old) * 100.0f) / (float)jiffies_total_delta); } *cpu_count = _cpu_count; @@ -178,12 +178,12 @@ get_cpu_percent (guint pid, gulong jiffies_user, gfloat *cpu_user, gulong jiffie if (_cpu_count > 0 && jiffies_total_delta > 0) { - *cpu_user = (jiffies_user - jiffies_user_old) * 100 / (gdouble)jiffies_total_delta; - *cpu_system = (jiffies_system - jiffies_system_old) * 100 / (gdouble)jiffies_total_delta; + *cpu_user = (((jiffies_user - jiffies_user_old) * 100.0f) / (float)jiffies_total_delta); + *cpu_system = (((jiffies_system - jiffies_system_old) * 100.0f) / (float)jiffies_total_delta); } else { - *cpu_user = *cpu_system = 0; + *cpu_user = *cpu_system = 0.0f; } } @@ -333,6 +333,8 @@ get_task_list (GArray *task_list) g_dir_close (dir); + g_array_sort (task_list, task_pid_compare_fn); + return TRUE; } diff --git a/src/task-manager-skel.c b/src/task-manager-skel.c index 5673523..c21d345 100644 --- a/src/task-manager-skel.c +++ b/src/task-manager-skel.c @@ -41,7 +41,7 @@ get_memory_usage (guint64 *memory_total, guint64 *memory_free, guint64 *memory_c gboolean get_cpu_usage (gushort *cpu_count, gfloat *cpu_user, gfloat *cpu_system) { - *cpu_user = *cpu_system = 0.0; + *cpu_user = *cpu_system = 0.0f; *cpu_count = 0; /*_cpu_count;*/ return TRUE; @@ -75,6 +75,8 @@ get_task_list (GArray *task_list) } } + g_array_sort (task_list, task_pid_compare_fn); + return TRUE; } diff --git a/src/task-manager-solaris.c b/src/task-manager-solaris.c index 0fe53e3..77bba26 100644 --- a/src/task-manager-solaris.c +++ b/src/task-manager-solaris.c @@ -112,12 +112,12 @@ get_cpu_percent (guint pid, gulong ticks_user, gfloat *cpu_user, gulong ticks_sy if (_cpu_count > 0 && ticks_total_delta > 0) { - *cpu_user = (ticks_user - ticks_user_old) * 100 / (gdouble)ticks_total_delta; - *cpu_system = (ticks_system - ticks_system_old) * 100 / (gdouble)ticks_total_delta; + *cpu_user = (((ticks_user - ticks_user_old) * 100.0f) / (float)ticks_total_delta); + *cpu_system = (((ticks_system - ticks_system_old) * 100.0f) / (float)ticks_total_delta); } else { - *cpu_user = *cpu_system = 0; + *cpu_user = *cpu_system = 0.0f; } } @@ -198,7 +198,7 @@ get_task_details (guint pid, Task *task) pw = getpwuid (process.pr_uid); task->uid = (guint)process.pr_uid; g_strlcpy (task->uid_name, (pw != NULL) ? pw->pw_name : "nobody", sizeof (task->uid_name)); - get_cpu_percent (task->pid, process.pr_time.tv_sec * 1000 + process.pr_time.tv_nsec / 100000, &task->cpu_user, 0, &task->cpu_system); + get_cpu_percent (task->pid, (process.pr_time.tv_sec * 1000 + process.pr_time.tv_nsec / 100000), &task->cpu_user, 0, &task->cpu_system); fclose (file); @@ -227,6 +227,8 @@ get_task_list (GArray *task_list) g_dir_close (dir); + g_array_sort (task_list, task_pid_compare_fn); + return FALSE; } diff --git a/src/task-manager.c b/src/task-manager.c index b63dfc9..a0adebc 100644 --- a/src/task-manager.c +++ b/src/task-manager.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2010 Mike Massonnet, + * Copyright (c) 2018 Rozhuk Ivan * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -11,6 +12,7 @@ #include #endif +#include #include #include #include @@ -73,16 +75,14 @@ static void xtm_task_manager_finalize (GObject *object); static void setting_changed (GObject *object, GParamSpec *pspec, XtmTaskManager *manager); #ifdef HAVE_WNCK static void model_add_task (GtkTreeModel *model, Task *task, App *app, glong timestamp); -static void model_update_tree_iter (GtkTreeModel *model, GtkTreeIter *iter, Task *task, App *app); -static void model_update_task (GtkTreeModel *model, Task *task, App *app); +static void model_update_tree_iter (GtkTreeModel *model, GtkTreeIter *iter, glong timestamp, gboolean update_cmd_line, Task *task, App *app); #else static void model_add_task (GtkTreeModel *model, Task *task, glong timestamp); -static void model_update_tree_iter (GtkTreeModel *model, GtkTreeIter *iter, Task *task); -static void model_update_task (GtkTreeModel *model, Task *task); +static void model_update_tree_iter (GtkTreeModel *model, GtkTreeIter *iter, glong timestamp, gboolean update_cmd_line, Task *task); #endif -static void model_mark_tree_iter_as_removed (GtkTreeModel *model, GtkTreeIter *iter); +static void model_mark_tree_iter_as_removed (GtkTreeModel *model, GtkTreeIter *iter, glong timestamp); static void model_remove_tree_iter (GtkTreeModel *model, GtkTreeIter *iter); -static void model_find_tree_iter_for_pid (GtkTreeModel *model, guint pid, GtkTreeIter *iter); +static gboolean task_list_find_for_pid (GArray *task_list, guint pid, Task **task, guint *idx); static glong __current_timestamp (void); @@ -169,46 +169,31 @@ model_add_task (GtkTreeModel *model, Task *task, glong timestamp) #endif { GtkTreeIter iter; - gchar *cmdline; - -#ifdef HAVE_WNCK - if (app != NULL && full_cmdline == FALSE) - cmdline = g_strdup (app->name); - else - cmdline = pretty_cmdline (task->cmdline, task->name); -#else - cmdline = pretty_cmdline (task->cmdline, task->name); -#endif gtk_list_store_append (GTK_LIST_STORE (model), &iter); gtk_list_store_set (GTK_LIST_STORE (model), &iter, - XTM_PTV_COLUMN_COMMAND, cmdline, XTM_PTV_COLUMN_PID, task->pid, XTM_PTV_COLUMN_STATE, task->state, XTM_PTV_COLUMN_UID, task->uid, XTM_PTV_COLUMN_UID_STR, task->uid_name, - XTM_PTV_COLUMN_BACKGROUND, NULL, - XTM_PTV_COLUMN_FOREGROUND, NULL, XTM_PTV_COLUMN_TIMESTAMP, timestamp, -1); #ifdef HAVE_WNCK - model_update_tree_iter (model, &iter, task, app); + model_update_tree_iter (model, &iter, timestamp, TRUE, task, app); #else - model_update_tree_iter (model, &iter, task); + model_update_tree_iter (model, &iter, timestamp, TRUE, task); #endif - - g_free (cmdline); } static void -model_mark_tree_iter_as_removed (GtkTreeModel *model, GtkTreeIter *iter) +model_mark_tree_iter_as_removed (GtkTreeModel *model, GtkTreeIter *iter, glong timestamp) { gtk_list_store_set (GTK_LIST_STORE (model), iter, XTM_PTV_COLUMN_CPU, 0.0, XTM_PTV_COLUMN_CPU_STR, "-", XTM_PTV_COLUMN_BACKGROUND, "#e57373", XTM_PTV_COLUMN_FOREGROUND, "#000000", - XTM_PTV_COLUMN_TIMESTAMP, __current_timestamp (), + XTM_PTV_COLUMN_TIMESTAMP, timestamp, -1); } @@ -220,9 +205,9 @@ model_remove_tree_iter (GtkTreeModel *model, GtkTreeIter *iter) static void #ifdef HAVE_WNCK -model_update_tree_iter (GtkTreeModel *model, GtkTreeIter *iter, Task *task, App *app) +model_update_tree_iter (GtkTreeModel *model, GtkTreeIter *iter, glong timestamp, gboolean update_cmd_line, Task *task, App *app) #else -model_update_tree_iter (GtkTreeModel *model, GtkTreeIter *iter, Task *task) +model_update_tree_iter (GtkTreeModel *model, GtkTreeIter *iter, glong timestamp, gboolean update_cmd_line, Task *task) #endif { gchar *vsz, *rss, cpu[16]; @@ -237,8 +222,8 @@ model_update_tree_iter (GtkTreeModel *model, GtkTreeIter *iter, Task *task) vsz = g_format_size_full (task->vsz, G_FORMAT_SIZE_IEC_UNITS); rss = g_format_size_full (task->rss, G_FORMAT_SIZE_IEC_UNITS); - g_snprintf (value, 14, (more_precision) ? "%.2f" : "%.0f", task->cpu_user + task->cpu_system); - g_snprintf (cpu, 16, _("%s%%"), value); + g_snprintf (value, sizeof(value), (more_precision) ? "%.2f" : "%.0f", (task->cpu_user + task->cpu_system)); + g_snprintf (cpu, sizeof(cpu), _("%s%%"), value); /* Retrieve values for tweaking background/foreground color and updating content as needed */ gtk_tree_model_get (model, iter, XTM_PTV_COLUMN_TIMESTAMP, &old_timestamp, XTM_PTV_COLUMN_STATE, &old_state, @@ -258,9 +243,9 @@ model_update_tree_iter (GtkTreeModel *model, GtkTreeIter *iter, Task *task) gtk_list_store_set (GTK_LIST_STORE (model), iter, XTM_PTV_COLUMN_COMMAND, cmdline, -1); g_free (cmdline); } - else if (model_update_forced) + else if (update_cmd_line) #else - if (model_update_forced) + if (update_cmd_line) #endif { gchar *cmdline = pretty_cmdline (task->cmdline, task->name); @@ -273,10 +258,10 @@ model_update_tree_iter (GtkTreeModel *model, GtkTreeIter *iter, Task *task) /* Set yellow color for changing state */ background = g_strdup ("#fff176"); foreground = g_strdup ("#000000"); - old_timestamp = __current_timestamp () - TIMESTAMP_DELTA + 3; + old_timestamp = timestamp - TIMESTAMP_DELTA + 3; } - if (__current_timestamp () - old_timestamp <= TIMESTAMP_DELTA) + if ((timestamp - old_timestamp) <= TIMESTAMP_DELTA) { /* Set green color for started task */ background = (background == NULL) ? g_strdup ("#aed581") : background; @@ -311,36 +296,29 @@ model_update_tree_iter (GtkTreeModel *model, GtkTreeIter *iter, Task *task) g_free (rss); } -static void -#ifdef HAVE_WNCK -model_update_task (GtkTreeModel *model, Task *task, App *app) -#else -model_update_task (GtkTreeModel *model, Task *task) -#endif +static gboolean +task_list_find_for_pid (GArray *task_list, guint pid, Task **task, guint *idx) { - GtkTreeIter iter; - model_find_tree_iter_for_pid (model, task->pid, &iter); -#ifdef HAVE_WNCK - model_update_tree_iter (model, &iter, task, app); -#else - model_update_tree_iter (model, &iter, task); -#endif -} + Task *task_tmp, tkey; + tkey.pid = pid; + task_tmp = bsearch(&tkey, task_list->data, task_list->len, sizeof(Task), task_pid_compare_fn); -static void -model_find_tree_iter_for_pid (GtkTreeModel *model, guint pid, GtkTreeIter *iter) -{ - gboolean valid; - guint pid_iter; - - valid = gtk_tree_model_get_iter_first (model, iter); - while (valid) + if (NULL != task) { - gtk_tree_model_get (model, iter, XTM_PTV_COLUMN_PID, &pid_iter, -1); - if (pid == pid_iter) - break; - valid = gtk_tree_model_iter_next (model, iter); + (*task) = task_tmp; } + if (NULL != idx) + { + if (NULL != task_tmp) + { + (*idx) = (((size_t)task_tmp - (size_t)task_list->data) / sizeof(Task)); + } + else + { + (*idx) = (~((guint)0)); + } + } + return ((NULL != task_tmp)); } static glong @@ -419,197 +397,123 @@ xtm_task_manager_get_task_list (XtmTaskManager *manager) void xtm_task_manager_update_model (XtmTaskManager *manager) { - static GArray *removed_tasks = NULL; GArray *array; guint i; + GtkTreeIter iter; + gboolean valid; + glong timestamp; g_return_if_fail (XTM_IS_TASK_MANAGER (manager)); - if (removed_tasks == NULL) - removed_tasks = g_array_new (FALSE, FALSE, sizeof (GtkTreeIter)); - - /* Retrieve initial task list and return */ - if (manager->tasks->len == 0) - { - get_task_list (manager->tasks); - for (i = 0; i < manager->tasks->len; i++) - { - Task *task = &g_array_index (manager->tasks, Task, i); -#ifdef HAVE_WNCK - App *app = xtm_app_manager_get_app_from_pid (manager->app_manager, task->pid); - model_add_task (manager->model, task, app, 0); -#else - model_add_task (manager->model, task, 0); -#endif -#if DEBUG - g_print ("%5d %5s %15s %.50s\n", task->pid, task->uid_name, task->name, task->cmdline); -#endif - } - return; - } + /* First time fast refresh. */ + timestamp = ((manager->tasks->len == 0) ? 0 : __current_timestamp ()); /* Retrieve new task list */ array = g_array_new (FALSE, FALSE, sizeof (Task)); get_task_list (array); - /* Remove terminated tasks */ - for (i = 0; i < removed_tasks->len; i++) + /* Remove terminated tasks, mark to remove, update existing. */ + valid = gtk_tree_model_get_iter_first (manager->model, &iter); + while (valid) { - GtkTreeIter *iter = &g_array_index (removed_tasks, GtkTreeIter, i); + gint pid; + gchar *cpu_str; glong old_timestamp; - gtk_tree_model_get (manager->model, iter, XTM_PTV_COLUMN_TIMESTAMP, &old_timestamp, -1); - if (__current_timestamp () - old_timestamp > TIMESTAMP_DELTA) + gboolean found; + Task *task, *task_new; + GtkTreeIter cur_iter = iter; + + gtk_tree_model_get (manager->model, &iter, XTM_PTV_COLUMN_CPU_STR, &cpu_str, XTM_PTV_COLUMN_TIMESTAMP, &old_timestamp, XTM_PTV_COLUMN_PID, &pid, -1); + found = (g_strcmp0 (cpu_str, "-") == 0); + g_free (cpu_str); + valid = gtk_tree_model_iter_next (manager->model, &iter); + if (found && (timestamp - old_timestamp) > TIMESTAMP_DELTA) { -#if DEBUG - gint pid; - gtk_tree_model_get (manager->model, iter, XTM_PTV_COLUMN_PID, &pid, -1); - g_debug ("Remove old task %d", pid); -#endif - model_remove_tree_iter (manager->model, iter); - g_array_remove_index (removed_tasks, i); + G_DEBUG_FMT ("Remove old task %d", pid); + model_remove_tree_iter (manager->model, &cur_iter); + continue; } - } - for (i = 0; i < manager->tasks->len; i++) - { - guint j; - Task *tasktmp; - Task *task = &g_array_index (manager->tasks, Task, i); - gboolean found = FALSE; - - for (j = 0; j < array->len; j++) + /* Looking for new terminated tasks and check updates for existing. */ + found = task_list_find_for_pid (manager->tasks, pid, &task, &i); + if (FALSE == found) { - tasktmp = &g_array_index (array, Task, j); - if (task->pid != tasktmp->pid) - continue; - found = TRUE; - break; + G_DEBUG_FMT ("Cached task not found for pid: %d", pid); + continue; } - - if (found == FALSE) + found = task_list_find_for_pid (array, pid, &task_new, NULL); + if (FALSE == found) /* Mark as removed. */ { - GtkTreeIter iter; -#if DEBUG - g_debug ("Task %d '%s' terminated, marking as removed", task->pid, task->name); -#endif - model_find_tree_iter_for_pid (manager->model, task->pid, &iter); - model_mark_tree_iter_as_removed (manager->model, &iter); - g_array_append_val (removed_tasks, iter); + G_DEBUG_FMT ("Task %d '%s' terminated, marking as removed", pid, task->name); + model_mark_tree_iter_as_removed (manager->model, &cur_iter, timestamp); g_array_remove_index (manager->tasks, i); + continue; } - } - - /* Append started tasks and update existing ones */ - for (i = 0; i < array->len; i++) - { - guint j; - Task *tasktmp = &g_array_index (array, Task, i); - gboolean found = FALSE; - for (j = 0; j < manager->tasks->len; j++) - { - Task *task = &g_array_index (manager->tasks, Task, j); + /* Task alive, check for update. */ #ifdef HAVE_WNCK - App *app; + App *app = xtm_app_manager_get_app_from_pid (manager->app_manager, pid); #endif - gboolean updated = FALSE; - - if (task->pid != tasktmp->pid) - continue; - -#ifdef HAVE_WNCK - app = xtm_app_manager_get_app_from_pid (manager->app_manager, task->pid); -#endif - found = TRUE; - - /* Update the model (with the rest) only if needed, this keeps the CPU cool */ - if (model_update_forced - || task->ppid != tasktmp->ppid - || g_strcmp0 (task->state, tasktmp->state) - || task->cpu_user != tasktmp->cpu_user - || task->cpu_system != tasktmp->cpu_system - || task->rss != tasktmp->rss - || task->vsz != tasktmp->vsz - || task->prio != tasktmp->prio) - { - updated = TRUE; - task->ppid = tasktmp->ppid; - g_strlcpy (task->state, tasktmp->state, sizeof (task->state)); - task->cpu_user = tasktmp->cpu_user; - task->cpu_system = tasktmp->cpu_system; - task->rss = tasktmp->rss; - task->vsz = tasktmp->vsz; - task->prio = tasktmp->prio; -#ifdef HAVE_WNCK - model_update_task (manager->model, tasktmp, app); -#else - model_update_task (manager->model, tasktmp); -#endif - } + gboolean need_update = FALSE; + gboolean update_cmd_line = FALSE; + /* Update the model (with the rest) only if needed, this keeps the CPU cool */ + if (model_update_forced || 0 != memcmp(task, task_new, sizeof(Task))) + { + need_update = TRUE; /* Update command name if needed (can happen) */ - if (!model_update_forced && g_strcmp0 (task->cmdline, tasktmp->cmdline)) - { - GtkTreeIter iter; - gchar *cmdline; - - cmdline = pretty_cmdline (tasktmp->cmdline, tasktmp->name); - model_find_tree_iter_for_pid (manager->model, task->pid, &iter); - gtk_list_store_set (GTK_LIST_STORE (manager->model), &iter, XTM_PTV_COLUMN_COMMAND, cmdline, -1); - g_free (cmdline); - } + update_cmd_line = (model_update_forced || g_strcmp0 (task->cmdline, task_new->cmdline)); + memcpy(task, task_new, sizeof(Task)); + } + else /* Update color if needed */ + { + gchar *color; - /* Update color if needed */ - if (updated == FALSE) + gtk_tree_model_get (manager->model, &cur_iter, XTM_PTV_COLUMN_BACKGROUND, &color, -1); + if (color != NULL && (timestamp - old_timestamp) > TIMESTAMP_DELTA) { - GtkTreeIter iter; - gchar *color; - glong old_timestamp; - - model_find_tree_iter_for_pid (manager->model, task->pid, &iter); - gtk_tree_model_get (manager->model, &iter, XTM_PTV_COLUMN_BACKGROUND, &color, XTM_PTV_COLUMN_TIMESTAMP, &old_timestamp, -1); - - if (color != NULL && __current_timestamp () - old_timestamp > TIMESTAMP_DELTA) - { -#if DEBUG - g_debug ("Remove color from running PID %d", task->pid); -#endif + need_update = TRUE; + G_DEBUG_FMT ("Remove color from running PID %d", pid); + } + g_free (color); + } + + if (need_update) + { #ifdef HAVE_WNCK - model_update_task (manager->model, tasktmp, app); + model_update_tree_iter (manager->model, &cur_iter, timestamp, update_cmd_line, task_new, app); #else - model_update_task (manager->model, tasktmp); + model_update_tree_iter (manager->model, &cur_iter, timestamp, update_cmd_line, task_new); #endif - } - - g_free (color); - } - - break; } + } - if (found == FALSE) - { + /* Append started tasks and update existing ones */ + for (i = 0; i < array->len; i++) + { + Task *tasktmp = &g_array_index (array, Task, i); + + if (task_list_find_for_pid (manager->tasks, tasktmp->pid, NULL, NULL)) + continue; #ifdef HAVE_WNCK - App *app = xtm_app_manager_get_app_from_pid (manager->app_manager, tasktmp->pid); - model_add_task (manager->model, tasktmp, app, __current_timestamp ()); + App *app = xtm_app_manager_get_app_from_pid (manager->app_manager, tasktmp->pid); + model_add_task (manager->model, tasktmp, app, timestamp); #else - model_add_task (manager->model, tasktmp, __current_timestamp ()); + model_add_task (manager->model, tasktmp, timestamp); #endif - g_array_append_val (manager->tasks, *tasktmp); -#if DEBUG - g_debug ("Add new task %d %s", tasktmp->pid, tasktmp->name); -#endif - } + /* XXX: add bininsert() here. */ + g_array_append_val (manager->tasks, *tasktmp); + g_array_sort (manager->tasks, task_pid_compare_fn); + G_DEBUG_FMT ("Add new task %d %s", tasktmp->pid, tasktmp->name); } g_array_free (array, TRUE); model_update_forced = FALSE; return; } - void get_owner_uid (guint *owner_uid, gchar **owner_uid_name) { @@ -633,7 +537,7 @@ get_hostname (void) #define HOST_NAME_MAX 255 #endif char hostname[HOST_NAME_MAX]; - if (gethostname (hostname, HOST_NAME_MAX)) + if (gethostname (hostname, sizeof(hostname))) return g_strdup ("(unknown)"); return g_strdup_printf ("%s", hostname); } @@ -693,3 +597,8 @@ set_priority_to_pid (guint pid, gint priority) return (res == 0) ? TRUE : FALSE; } +gint +task_pid_compare_fn(gconstpointer a, gconstpointer b) +{ + return (((Task*)a)->pid - ((Task*)b)->pid); +} diff --git a/src/task-manager.h b/src/task-manager.h index e74acd0..1a3c0bd 100644 --- a/src/task-manager.h +++ b/src/task-manager.h @@ -96,5 +96,14 @@ void get_owner_uid (guint *owner_uid, gchar **owner_uid_name); gchar * get_hostname (void); gboolean send_signal_to_pid (guint pid, gint xtm_signal); gboolean set_priority_to_pid (guint pid, gint priority); +gint task_pid_compare_fn (gconstpointer a, gconstpointer b); + + +#if DEBUG +# define G_DEBUG_FMT(fmt, args...) g_debug((fmt), ##args) +#else +# define G_DEBUG_FMT(fmt, args...) +#endif + #endif /* !TASK_MANAGER_H */ -- libgit2 0.27.0