Hi there,
Here this patch focus on performance optimization for g-s-m.
Have done below:
1. Delete all readlink sys-call so that readlink never called in normal
loop until some special information needed, it will save lots of time...
2. Remove 4 psinfo file open/pread/close call for each process when
update display every interval, and merge these functions into 1
function, now it will open/close once for each process. it also will
save lots of cpu time.
3. Remove one xmap file open/pread/close call for each process when
update display every interval, and merge the functions into another one,
so that only run once open/close.
4. Change to get some information we need in aother better way to save
some time
5. Delete "objfs" and "ctfs" type of file from File System tap.
The biggest burden here is pread, because the original writer designed
this architecture, it have to read all needed information every interval
from different directories and files at Solaris, while Linux one can get
almost of them from the same place. Now the performance is similar with
the one at Linux. But can't do more at the moment, if change bigger
currently, will cause some risk for this app. functionality.
============================================================================
diff -Nrup libgtop-2.14.4/include/glibtop/procstate.h
libgtop-2.14.4.mod/include/glibtop/procstate.h
--- libgtop-2.14.4/include/glibtop/procstate.h 2006-09-11
05:53:29.000000000 +0800
+++ libgtop-2.14.4.mod/include/glibtop/procstate.h 2006-11-25
23:20:40.952117000 +0800
@@ -66,11 +66,17 @@ struct _glibtop_proc_state
* fields if their values are corrent ! */
int uid; /* UID of process */
int gid; /* GID of process */
- int ruid;
- int rgid;
- int has_cpu;
- int processor;
- int last_processor;
+ int ruid;
+ int rgid;
+ int has_cpu;
+ int processor;
+ int last_processor;
+
+ gint32 nice; /*zhua: used to store nice */
+ guint64 start_time; /* start time of process -- */
+ guint64 vsize; /* number of pages of virtual memory ... */
+ guint64 resident; /* number of resident set */
+ guint load; /* cpu load for process */
};
diff -Nrup libgtop-2.14.4/sysdeps/common/mountlist.c
libgtop-2.14.4.mod/sysdeps/common/mountlist.c
--- libgtop-2.14.4/sysdeps/common/mountlist.c 2006-06-25
01:24:27.000000000 +0800
+++ libgtop-2.14.4.mod/sysdeps/common/mountlist.c 2006-11-26
09:16:03.955824000 +0800
@@ -584,7 +586,17 @@ glibtop_get_mountlist_s (glibtop *server
return NULL;
for (cur = &entries[0]; cur != NULL; cur = next) {
-
+ /*zhua: delete these 2 type of fs: objfs,ctfs */
+ if (!strcmp(cur->me_type, "objfs") || !strcmp(cur->me_type,"ctfs")){
+ /* free current mount_entry and move to the next */
+ next = cur->me_next;
+ g_free(cur->me_devname);
+ g_free(cur->me_mountdir);
+ g_free(cur->me_type);
+ g_free(cur);
+ continue;
+ }
+
diff -Nrup libgtop-2.14.4/sysdeps/solaris/netlist.c
libgtop-2.14.4.mod/sysdeps/solaris/netlist.c
--- libgtop-2.14.4/sysdeps/solaris/netlist.c 2006-06-25
01:33:05.000000000 +0800
+++ libgtop-2.14.4.mod/sysdeps/solaris/netlist.c 2006-11-25
20:43:10.868753000 +0800
@@ -41,7 +41,13 @@ glibtop_get_netlist_s (glibtop *server,
{
GPtrArray *devices;
kstat_t *ksp;
- kstat_ctl_t *kc;
+ /* use the kc installed in server, don't need to create again,
+ it will save some time and improve performance */
+ kstat_ctl_t * const kc = server->machine.kc;
+ /* use flags as a check condition, if it is 1, check, or not check...
zhua */
+ int check = buf->flags;
+ /* set flags back to 0 */
+ buf->flags = 0;
glibtop_init_s (&server, GLIBTOP_SYSDEPS_NETLIST, 0);
@@ -49,9 +55,9 @@ glibtop_get_netlist_s (glibtop *server,
devices = g_ptr_array_new();
- kc = kstat_open();
if (kc == NULL) {
glibtop_warn_io_r(server, "kstat_open()");
+ buf->number = 0;
return NULL;
}
@@ -60,12 +66,27 @@ glibtop_get_netlist_s (glibtop *server,
if (strcmp(ksp->ks_class, "net") != 0)
continue;
- g_ptr_array_add(devices, g_strdup(ksp->ks_name));
- buf->number++;
+ /* do some check to see if the first character is the same between
+ name and module, if not, we don't return it, because
+ glibtop_get_netload() only want the same ones, it will save some time....
+ */
+ if (check){
+ /* if the first character is not same, they should not
+ the one we will use in glibtop_get_netload() */
+ if (ksp->ks_name[0] != ksp->ks_module[0])
+ continue;
+ /* because in glibtop_get_netload(), name
+ is at least 1 character longer than module */
+ if (strlen( ksp->ks_module ) >= strlen( ksp->ks_name))
+ continue;
+ /* if it's not digital, continue directly */
+ if( !isdigit( (int) ksp->ks_name[strlen( ksp->ks_module )] ))
+ continue;
+ }
+ g_ptr_array_add(devices, g_strdup(ksp->ks_name));
+ buf->number++;
}
diff -Nrup libgtop-2.14.4/sysdeps/solaris/procmap.c
libgtop-2.14.4.mod/sysdeps/solaris/procmap.c
--- libgtop-2.14.4/sysdeps/solaris/procmap.c 2006-06-25
01:45:29.000000000 +0800
+++ libgtop-2.14.4.mod/sysdeps/solaris/procmap.c 2006-11-26
02:14:50.689720000 +0800
@@ -56,6 +56,12 @@ glibtop_map_entry *
glibtop_get_proc_map_s (glibtop *server, glibtop_proc_map *buf, pid_t pid)
{
int fd, i, nmaps, pr_err, heap;
+ char filename [BUFSIZ];
+ /* use flags as a check condition, if it is 1, check, or, not check...
zhua */
+ int check = buf->flags;
+ /* set flags back to 0 */
+ buf->flags = 0;
+
@@ -125,15 +131,26 @@ glibtop_get_proc_map_s (glibtop *server,
buf->total = nmaps * sizeof(glibtop_map_entry);
entry = g_malloc0(buf->total);
-#if GLIBTOP_SOLARIS_RELEASE >= 50600
-
- if(server->machine.objname && server->machine.pgrab &&
- server->machine.pfree)
- Pr = (server->machine.pgrab)(pid, 1, &pr_err);
-#endif
for(heap = 0,i = 0; i < nmaps; ++i)
{
- int len;
+ /* zhua: take a check to see if we need all information, if not, just
get what we need..
+ Also please see comments in get_process_memory_writable() of
gnome-system-monitor zhua */
+ if (check == 1)
+ {
+ if(maps[i].pr_mflags & MA_WRITE){
+ entry[i].perm |= GLIBTOP_MAP_PERM_WRITE;
+ entry[i].size = maps[i].pr_size;
+ }
+
+ if(maps[i].pr_mflags & MA_SHARED){
+ entry[i].perm |= GLIBTOP_MAP_PERM_SHARED;
+ /* here use shared_clean to store Shared Memory */
+ entry[i].shared_clean = maps[i].pr_size;
+ }
+ }
+ else {
+
diff -Nrup libgtop-2.14.4/sysdeps/solaris/procstate.c
libgtop-2.14.4.mod/sysdeps/solaris/procstate.c
--- libgtop-2.14.4/sysdeps/solaris/procstate.c 2005-12-12
18:09:40.000000000 +0800
+++ libgtop-2.14.4.mod/sysdeps/solaris/procstate.c 2006-11-25
23:18:34.641117000 +0800
@@ -64,6 +64,26 @@ glibtop_get_proc_state_s (glibtop *serve
buf->gid = psinfo.pr_egid;
buf->ruid = psinfo.pr_uid;
buf->rgid = psinfo.pr_gid;
+ /* zhua: get some value here, so that we don't need run
open/pread/close psinfo later,
and can delete some other call for psinfo open/pread/close. it will save
lots of time*/
+#ifdef HAVE_PROCFS_H
+ buf->nice = psinfo.pr_lwp.pr_nice - NZERO;
+#else
+ buf->nice = psinfo.pr_nice - NZERO;
+#endif
+
+ buf->start_time = psinfo.pr_start.tv_sec;
+
+#ifdef HAVE_PROCFS_H
+ buf->vsize = psinfo.pr_size << 10;
+ buf->resident= psinfo.pr_rssize << 10;
+ buf->load = (guint) psinfo.pr_lwp.pr_pctcpu * 100 / (guint) 0x8000;
+#else
+ buf->vsize = psinfo.pr_size << pagesize << 10;
+ buf->resident = psinfo.pr_rssize << pagesize << 10;
+ buf->load = (guint) psinfo.pr_lwp.pr_pctcpu * 100 / (guint) 0x8000;
+#endif
diff -Nrup libgtop-2.14.4/sysdeps/solaris/proctime.c
libgtop-2.14.4.mod/sysdeps/solaris/proctime.c
--- libgtop-2.14.4/sysdeps/solaris/proctime.c 2006-06-25
01:47:34.000000000 +0800
+++ libgtop-2.14.4.mod/sysdeps/solaris/proctime.c 2006-11-25
21:37:39.825507000 +0800
@@ -45,8 +45,12 @@ void
+ /* zhua remove this function call, because we can change to get
start_time in
+ glibtop_get_proc_state(), it don't need open psinfo again here
+ if (glibtop_get_proc_data_psinfo_s(server, &pinfo, pid))
+ return;
+ buf->start_time = pinfo.pr_start.tv_sec;*/
+diff -Nrup gnome-system-monitor-2.16.1/src/load-graph.c
gnome-system-monitor-2.16.1.mod/src/load-graph.c
--- gnome-system-monitor-2.16.1/src/load-graph.c 2006-08-18
00:50:03.000000000 +0800
+++ gnome-system-monitor-2.16.1.mod/src/load-graph.c 2006-11-25
21:17:25.949908000 +0800
@@ -348,6 +348,20 @@ get_net (LoadGraph *g)
float din, dout;
gchar *text1, *text2;
+ /* we have to optimize the performance of libgtop, because in some low
level machine,
+ to update the information will occupy too much cpu.
+
+ here I would like to make a little update:set
glibtop_netlist.flags=1,so as to let glibtop_get_netlist()
+ only return the ones whose first character of name is the same with
the first one in their module,
+ glibtop_get_netload() just try to find these devices, for example,
bge0 and bge...
+
+ we do the check in glibtop_get_netlist(), I think this will accelerate
the transaction lots,
+ Also this will not affect the existing codes, because when nobody set
glibtop_netlist.flags,
+ glibtop_get_netlist() will return all devices with class "net".
+ */
+
+ netlist.flags = 1;
+
ifnames = glibtop_get_netlist(&netlist);
diff -Nrup gnome-system-monitor-2.16.1/src/proctable.c
gnome-system-monitor-2.16.1.mod/src/proctable.c
--- gnome-system-monitor-2.16.1/src/proctable.c 2006-08-31
02:11:01.000000000 +0800
+++ gnome-system-monitor-2.16.1.mod/src/proctable.c 2006-11-26
02:23:26.374020000 +0800
@@ -556,6 +556,17 @@ static void get_process_memory_writable(
unsigned i;
info->memwritable = 0;
+ /* we have to optimize the performance of libgtop, because update the
information will occupy too much cpu.
+
+ here I would like to make a little update:set
glibtop_proc_map.flags=1,so as to let glibtop_get_proc_map_s()
+ only return the ones this function need: memwritable
+
+ we do the check in glibtop_get_proc_map_s(), don't run the others part
which don't need by this function,
+ I think this will accelerate the transaction lots,
+ Also this will not affect the existing codes, because when nobody set
glibtop_proc_map.flags,
+ glibtop_get_proc_map() will return all as before. zhua
+ */
+ buf.flags = 1;
maps = glibtop_get_proc_map(&buf, info->pid);
@@ -565,6 +576,9 @@ static void get_process_memory_writable(
#else
if (maps[i].perm & GLIBTOP_MAP_PERM_WRITE)
info->memwritable += maps[i].size;
+
+ if (maps[i].perm & GLIBTOP_MAP_PERM_SHARED)
+ info->memshared += maps[i].shared_clean;
#endif
}
@@ -581,17 +595,28 @@ get_process_memory_info(ProcInfo *info)
wnck_pid_read_resource_usage (gdk_screen_get_display
(gdk_screen_get_default ()),
info->pid,
&xresources);
-
+ info->memxserver = xresources.total_bytes_estimate;
+
+ /*zhua: we have to optimize the performance of libgtop, because update
the information will occupy too much cpu.
+ optimize the function call, let flags =1, so if glibtop_get_proc_mem()
+ find flags =1, don't call glibtop_get_proc_data_psinfo_s() */
+
+ /* zhua: use get_process_memory_writable(), because it just call
glibtop_get_proc_map_s(),
+ can get all need infor.
glibtop_get_proc_mem(&procmem, info->pid);
+
+ info->memshared = procmem.share;
info->vmsize = procmem.vsize;
info->memres = procmem.resident;
- info->memshared = procmem.share;
- info->memxserver = xresources.total_bytes_estimate;
+#ifdef __sun
+ info->pcpu = procmem.load;
+#endif
+ */
get_process_memory_writable(info);
-
+
@@ -846,19 +898,35 @@ update_info (ProcData *procdata, ProcInf
glibtop_proc_uid procuid;
glibtop_proc_time proctime;
- glibtop_get_proc_uid (&procuid, info->pid);
+ /* zhua: let's delete this call, because we can get the value
+ from glibtop_get_proc_state
+ glibtop_get_proc_uid (&procuid, info->pid);*/
glibtop_get_proc_time (&proctime, info->pid);
+ info->cpu_time_last = proctime.rtime;
- get_process_memory_info(info);
get_process_user(procdata, info, procstate.uid);
+ /* zhua: let's get from file directly
info->pcpu = (proctime.rtime - info->cpu_time_last) * 100 / total_time;
- info->pcpu = MIN(info->pcpu, 100);
-
- info->cpu_time_last = proctime.rtime;
- info->nice = procuid.nice;
+ info->pcpu = MIN(info->pcpu, 100);*/
+
+ /* zhua: get nice from procstate */
+ /*info->nice = procuid.nice;*/
+ info->nice = procstate.nice;
+
+ /* zhua: get start_time from procstate */
+ info->start_time = procstate.start_time;
+
+
+ /* if at Solaris, in get_process_memory_info() info->pcpu will
+ get again from glibtop_get_proc_mem() */
+ get_process_memory_info(info);
+ info->vmsize = procstate.vsize;
+ info->memres = procstate.resident;
+ info->pcpu = procstate.load;
+
model = gtk_tree_view_get_model (GTK_TREE_VIEW (procdata->tree));
update_info_mutable_cols(GTK_TREE_STORE (model), procdata, info);
@@ -896,7 +964,14 @@ procinfo_new (ProcData *procdata, gint p
info->pcpu = 0;
info->cpu_time_last = proctime.rtime;
- info->start_time = proctime.start_time;
+ /* zhua */
+ info->vmsize = procstate.vsize;
+ info->memres = procstate.resident;
+
+ info->pcpu = procstate.load;
+
+ info->start_time = procstate.start_time;
+ /*info->start_time = proctime.start_time; zhua */
info->nice = procuid.nice;
get_process_memory_info(info);
@@ -1017,9 +1092,10 @@ proctable_update_list (ProcData * const
/* FIXME: total cpu time elapsed should be calculated on an individual
basis here
** should probably have a total_time_last gint in the ProcInfo structure */
+ /* zhua: delete these sentences, we can get cpu% from file directly.
glibtop_get_cpu (&cpu);
- total_time = MAX(cpu.total - total_time_last, 1);
- total_time_last = cpu.total;
+ total_time = MAX(cpu.total - total_time_last, 1);
+ total_time_last = cpu.total;*/
refresh_list (procdata, pid_list, proclist.number);