diff --git a/src/task-manager-solaris.c b/src/task-manager-solaris.c new file mode 100644 index 0000000..afb8344 --- /dev/null +++ b/src/task-manager-solaris.c @@ -0,0 +1,217 @@ +/* + * Copyright (c) 2010 Mike Massonnet + * Copyright (c) 2009 Peter Tribble + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "task-manager.h" + +static kstat_ctl_t *kc; +static gushort _cpu_count = 0; + +static void +init_stats () +{ + kc = kstat_open (); +} + +gboolean +get_memory_usage (guint64 *memory_total, guint64 *memory_free, guint64 *memory_cache, guint64 *memory_buffers, guint64 *swap_total, guint64 *swap_free) +{ + kstat_t *ksp; + kstat_named_t *knp; + + if (!kc) + init_stats(); + + if (!(ksp = kstat_lookup (kc, "unix", 0, "system_pages"))) + return FALSE; + kstat_read (kc, ksp, NULL); + knp = kstat_data_lookup (ksp, "physmem"); + *memory_total = getpagesize () * knp->value.ui64; + knp = kstat_data_lookup (ksp, "freemem"); + *memory_free = getpagesize () * knp->value.ui64; + *memory_cache = 0; + + if (!(ksp = kstat_lookup (kc, "unix", 0, "vminfo"))) + return FALSE; + kstat_read (kc, ksp, NULL); + // TODO read swap usage + //knp = kstat_data_lookup (ksp, "..."); + *swap_total = 0; + *swap_free = 0; + + return TRUE; +} + +static void +get_cpu_percent (guint pid, gulong ticks_user, gfloat *cpu_user, gulong ticks_system, gfloat *cpu_system) +{ + static GHashTable *hash_cpu_user = NULL; + static GHashTable *hash_cpu_system = NULL; + gulong ticks_user_old, ticks_system_old; + + if (hash_cpu_user == NULL) + { + hash_cpu_user = g_hash_table_new (NULL, NULL); + hash_cpu_system = g_hash_table_new (NULL, NULL); + } + + ticks_user_old = GPOINTER_TO_UINT (g_hash_table_lookup (hash_cpu_user, GUINT_TO_POINTER (pid))); + ticks_system_old = GPOINTER_TO_UINT (g_hash_table_lookup (hash_cpu_system, GUINT_TO_POINTER (pid))); + g_hash_table_insert (hash_cpu_user, GUINT_TO_POINTER (pid), GUINT_TO_POINTER (ticks_user)); + g_hash_table_insert (hash_cpu_system, GUINT_TO_POINTER (pid), GUINT_TO_POINTER (ticks_system)); + + if (ticks_user < ticks_user_old || ticks_system < ticks_system_old) + return; + + if (_cpu_count > 0) + { + *cpu_user = (ticks_user_old > 0) ? (ticks_user - ticks_user_old) / (gfloat)_cpu_count : 0; + *cpu_system = (ticks_system_old > 0) ? (ticks_system - ticks_system_old) / (gfloat)_cpu_count : 0; + } + else + { + *cpu_user = *cpu_system = 0; + } +} + +gboolean +get_cpu_usage (gushort *cpu_count, gfloat *cpu_user, gfloat *cpu_system) +{ + kstat_t *ksp; + kstat_named_t *knp; + gulong ticks_user = 0, ticks_system = 0; + + if (!kc) + init_stats (); + + _cpu_count = 0; + kstat_chain_update (kc); + + for (ksp = kc->kc_chain; ksp != NULL; ksp = ksp->ks_next) + { + if (!g_strcmp0 (ksp->ks_module, "cpu_info")) + { + _cpu_count += 1; + } + else if (!g_strcmp0 (ksp->ks_module, "cpu") && !g_strcmp0 (ksp->ks_name, "sys")) + { + // TODO switch ticks to nsec for better precision + kstat_read (kc, ksp, NULL); + knp = kstat_data_lookup (ksp, "cpu_ticks_user"); + ticks_user += knp->value.ul; + knp = kstat_data_lookup (ksp, "cpu_ticks_kernel"); + ticks_system += knp->value.ul; + } + } + + get_cpu_percent (0, ticks_user, cpu_user, ticks_system, cpu_system); + *cpu_count = _cpu_count; + + return TRUE; +} + +static gboolean +get_task_details (guint pid, Task *task) +{ + FILE *file; + gchar filename[96]; + gchar pstate[2]; + struct passwd *pw; + psinfo_t process; + + snprintf (filename, 96, "/proc/%d/psinfo", pid); + if ((file = fopen (filename, "r")) == NULL) + return FALSE; + + if (fread (&process, sizeof (psinfo_t), 1, file) != 1) + { + fclose (file); + return FALSE; + } + + task->pid = (guint)process.pr_pid; + task->ppid = (guint)process.pr_ppid; + g_strlcpy (task->name, process.pr_fname, 256); + snprintf (task->cmdline, 1024, "%s", process.pr_psargs); + snprintf (task->state, 16, "%c", process.pr_lwp.pr_sname); + task->vsz = (guint64)process.pr_size * 1024; + task->rss = (guint64)process.pr_rssize * 1024; + task->prio = (gushort)process.pr_lwp.pr_pri; + 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 * 100000 + process.pr_time.tv_nsec / 1000, &task->cpu_user, 0, &task->cpu_system); + task->cpu_user /= 10000; + + fclose (file); + + return TRUE; +} + +gboolean +get_task_list (GArray *task_list) +{ + GDir *dir; + const gchar *name; + guint pid; + Task task = { 0 }; + + if ((dir = g_dir_open ("/proc", 0, NULL)) == NULL) + return FALSE; + + while ((name = g_dir_read_name(dir)) != NULL) + { + if ((pid = (guint)g_ascii_strtoull (name, NULL, 0)) > 0) + { + if (get_task_details (pid, &task)) + g_array_append_val(task_list, task); + } + } + + g_dir_close (dir); + + return FALSE; +} + +gboolean +pid_is_sleeping (guint pid) +{ + FILE *file; + gchar filename[96]; + gchar state[2]; + psinfo_t process; + + snprintf (filename, 96, "/proc/%d/psinfo", pid); + if ((file = fopen (filename, "r")) == NULL) + return FALSE; + + if (fread (&process, sizeof (psinfo_t), 1, file) != 1) + { + fclose (file); + return FALSE; + } + + snprintf (state, 2, "%c", process.pr_lwp.pr_sname); + fclose (file); + + return (state[0] == 'T') ? TRUE : FALSE; +} + diff --git a/src/taskmanager-solaris.c b/src/taskmanager-solaris.c deleted file mode 100644 index fc3e806..0000000 --- a/src/taskmanager-solaris.c +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Copyright (c) 2009 Peter Tribble - * - * 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 - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include "taskmanager.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -kstat_ctl_t *kc; - -static void init_stats() -{ - kc = kstat_open(); -} - -struct task get_task_details(gint pid) -{ - struct task task; - gchar filename[255]; - gchar pstate[2]; - int fd; - struct passwd *passwdp; - struct psinfo thisproc; - - sprintf(filename, "/proc/%i/psinfo", pid); - - task.pid = pid; - task.checked = FALSE; - - if ((fd = open(filename, O_RDONLY)) > 0) - { - if (read(fd, &thisproc, sizeof(psinfo_t)) == sizeof(psinfo_t)) - { - g_strlcpy(task.name,thisproc.pr_fname,64); - sprintf(pstate, "%c", thisproc.pr_lwp.pr_sname); - g_strlcpy(task.state, pstate, 16); - task.ppid = (gint) thisproc.pr_ppid; - task.prio = (gint) thisproc.pr_lwp.pr_pri; - task.vsize = (gint) thisproc.pr_size*1024; - task.rss = (gint) thisproc.pr_rssize*1024; - task.uid = (gint) thisproc.pr_uid; - passwdp = getpwuid(thisproc.pr_uid); - if(passwdp != NULL && passwdp->pw_name != NULL) - g_strlcpy(task.uname, passwdp->pw_name, sizeof task.uname); - /* - * To get the appropriate precision we need to multiply up by 10000 - * so that when we convert to a percentage we can represent 0.01%. - */ - task.old_time = task.time; - task.time = 10000*thisproc.pr_time.tv_sec + thisproc.pr_time.tv_nsec/100000; - task.time_percentage = 0; - } - close(fd); - } - - return task; -} - -GArray *get_task_list(void) -{ - DIR *dir; - struct dirent *dir_entry; - GArray *task_list; - - task_list = g_array_new (FALSE, FALSE, sizeof (struct task)); - - if((dir = opendir("/proc/")) == NULL) - { - fprintf(stderr, "Error: couldn't load the /proc directory\n"); - return NULL; - } - - gint count = 0; - - while((dir_entry = readdir(dir)) != NULL) - { - if(atoi(dir_entry->d_name) != 0) - { - struct task task = get_task_details(atoi(dir_entry->d_name)); - if(task.pid != -1) - g_array_append_val(task_list, task); - } - count++; - } - - closedir(dir); - - return task_list; -} - -gboolean get_cpu_usage_from_proc(system_status *sys_stat) -{ - gboolean retval = FALSE; - kstat_t *ksp; - kstat_named_t *knp; - - if (!kc) - { - init_stats(); - } - - if ( sys_stat->valid_proc_reading == TRUE ) { - sys_stat->cpu_old_jiffies = - sys_stat->cpu_user + - sys_stat->cpu_nice + - sys_stat->cpu_system+ - sys_stat->cpu_idle; - sys_stat->cpu_old_used = - sys_stat->cpu_user + - sys_stat->cpu_nice + - sys_stat->cpu_system; - } else { - sys_stat->cpu_old_jiffies = 0; - } - - sys_stat->valid_proc_reading = FALSE; - - kstat_chain_update(kc); - - for (ksp = kc->kc_chain; ksp != NULL; ksp = ksp->ks_next) - { - if (!strcmp(ksp->ks_module, "cpu") && !strcmp(ksp->ks_name, "sys")) - { - kstat_read(kc, ksp, NULL); - knp = kstat_data_lookup(ksp, "cpu_ticks_user"); - sys_stat->cpu_user = knp->value.ui64; - knp = kstat_data_lookup(ksp, "cpu_ticks_kernel"); - sys_stat->cpu_system = knp->value.ui64; - knp = kstat_data_lookup(ksp, "cpu_ticks_idle"); - sys_stat->cpu_idle = knp->value.ui64; - sys_stat->cpu_nice = 0L; - sys_stat->valid_proc_reading = TRUE; - retval = TRUE; - } - } - return retval; -} - -gboolean get_system_status (system_status *sys_stat) -{ - kstat_t *ksp; - kstat_named_t *knp; - - if (!kc) - { - init_stats(); - } - - if (ksp = kstat_lookup(kc, "unix", 0, "system_pages")) - { - kstat_read(kc, ksp, NULL); - knp = kstat_data_lookup(ksp, "physmem"); - sys_stat->mem_total = (getpagesize()*knp->value.ui64)/1024; - knp = kstat_data_lookup(ksp, "freemem"); - sys_stat->mem_free = (getpagesize()*knp->value.ui64)/1024; - sys_stat->mem_cached = 0; - } - - sys_stat->cpu_count = 0; - kstat_chain_update(kc); - - for (ksp = kc->kc_chain; ksp != NULL; ksp = ksp->ks_next) - { - if (!strcmp(ksp->ks_module, "cpu_info")) - { - sys_stat->cpu_count++; - } - } - - return TRUE; -} - -void send_signal_to_task(gint task_id, gint signal) -{ - if(task_id > 0 && signal != 0) - { - gint ret = 0; - - ret = kill(task_id, signal); - - if(ret != 0) - xfce_err(_("Couldn't send signal %d to the task with ID %d"), signal, task_id); - } -} - - -void set_priority_to_task(gint task_id, gint prio) -{ - if(task_id > 0) - { - gchar command[128] = ""; - g_snprintf(command, 128, "/usr/bin/priocntl -s -p %d -i pid %d > /dev/null", prio, task_id); - /* - * priocntl always returns 0, so this test is useless until - * priocntl gets fixed - */ - if(system(command) != 0) - xfce_err(_("Couldn't set priority %d to the task with ID %d"), prio, task_id); - } -} - diff --git a/src/taskmanager.h b/src/taskmanager.h deleted file mode 100644 index 79cdc0e..0000000 --- a/src/taskmanager.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2006 Johannes Zellner - * Copyright (c) 2008 Mike Massonnet - * - * 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 - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef TASKMANAGER_H -#define TASKMANAGER_H - -#include -#include - -#include "types.h" - -GArray *get_task_list(void); -gboolean get_system_status(system_status *sys_stat); -gboolean get_cpu_usage_from_proc(system_status *sys_stat); -void send_signal_to_task(gint task_id, gint signal); -void set_priority_to_task(gint task_id, gint prio); - -#endif - diff --git a/src/types.h b/src/types.h deleted file mode 100644 index 56e617e..0000000 --- a/src/types.h +++ /dev/null @@ -1,102 +0,0 @@ -/* $Id$ - * - * Copyright (c) 2006 Johannes Zellner - * 2008 Mike Massonnet - * - * 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 - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef TYPES_H -#define TYPES_H - -#include - -#define REFRESH_INTERVAL 1000 - -struct task -{ - gint pid; - gint ppid; - gint uid; - gchar uname[64]; - gchar name[64]; - gchar fullname[255]; - gchar state[16]; - gint vsize; - gint rss; - gboolean checked; - gint time; - gint old_time; - gdouble time_percentage; - gdouble old_time_percentage; - gint prio; /* my change */ -}; - -typedef struct -{ - guint mem_total; - guint mem_free; - guint mem_cached; - guint mem_buffers; - guint cpu_count; - guint cpu_idle; - guint cpu_user; - guint cpu_nice; - guint cpu_system; - guint cpu_old_jiffies; - guint cpu_old_used; - gboolean valid_proc_reading; -} system_status; - -GtkWidget *main_window; - -GArray *task_array; -gint tasks; -gint own_uid; - -gchar *config_file; - -gboolean show_user_tasks; -gboolean show_root_tasks; -gboolean show_other_tasks; - -gboolean show_cached_as_free; /* Show memory used Cache as free memory */ - -guint sort_column; -guint sort_type; - -enum -{ - COLUMN_NAME = 0, - COLUMN_PID, - COLUMN_PPID, - COLUMN_STATE, - COLUMN_MEM, - COLUMN_RSS, - COLUMN_UNAME, - COLUMN_TIME, - COLUMN_PRIO, - N_COLUMNS, -}; - -gboolean show_col[N_COLUMNS]; - -guint win_width; -guint win_height; - -const gchar *custom_signal_0; -const gchar *custom_signal_1; - -#endif