gnome-system-monitor r2378 - trunk/src



Author: bdejean
Date: Sat Apr  5 17:50:45 2008
New Revision: 2378
URL: http://svn.gnome.org/viewvc/gnome-system-monitor?rev=2378&view=rev

Log:
Cache username from getpwuid to save hundreds of open("/etc/passwd", ...).


Modified:
   trunk/src/procman.cpp
   trunk/src/procman.h
   trunk/src/proctable.cpp

Modified: trunk/src/procman.cpp
==============================================================================
--- trunk/src/procman.cpp	(original)
+++ trunk/src/procman.cpp	Sat Apr  5 17:50:45 2008
@@ -236,12 +236,6 @@
 
 	pd = ProcData::get_instance();
 
-	/* username is usually 8 chars long
-	   for caching, we create chunks of 128 chars */
-	pd->users = g_string_chunk_new(128);
-	/* push empty string */
-	g_string_chunk_insert_const(pd->users, "");
-
 	pd->config.width = gconf_client_get_int (client, "/apps/procman/width", NULL);
 	pd->config.height = gconf_client_get_int (client, "/apps/procman/height", NULL);
 	pd->config.show_tree = gconf_client_get_bool (client, "/apps/procman/show_tree", NULL);
@@ -370,7 +364,6 @@
 {
 
 	proctable_free_table (procdata);
-	g_string_chunk_free(procdata->users);
 	delete procdata->smooth_refresh;
 }
 

Modified: trunk/src/procman.h
==============================================================================
--- trunk/src/procman.h	(original)
+++ trunk/src/procman.h	Sat Apr  5 17:50:45 2008
@@ -29,6 +29,7 @@
 #include <glibtop/cpu.h>
 
 #include <time.h>
+#include <sys/types.h>
 
 #include <map>
 #include <string>
@@ -103,8 +104,8 @@
       status(0)
   { }
 
-  // allocated with g_string_chunk, don't free it !
-  gchar* user;
+  // shared, don't free it !
+  const gchar* user;
 
   // all these members are filled with libgtop which uses
   // guint64 (to have fixed size data) but we don't need more
@@ -132,6 +133,11 @@
 {
 	/* undefined */ ProcInfo& operator=(const ProcInfo&);
 	/* undefined */ ProcInfo(const ProcInfo&);
+
+	typedef std::map<guint, const char*> UserMap;
+	/* cached username */
+	static UserMap users;
+
  public:
 
 	// TODO: use a set instead
@@ -152,6 +158,7 @@
 	~ProcInfo();
 	// adds one more ref to icon
 	void set_icon(Glib::RefPtr<Gdk::Pixbuf> icon);
+	void set_user(guint uid);
 
 	GtkTreeIter	node;
 	Glib::RefPtr<Gdk::Pixbuf> pixbuf;
@@ -206,10 +213,6 @@
 	GtkWidget	*app;
 	GtkUIManager	*menu;
 
-
-	/* cached username */
-	GStringChunk	*users;
-
 	unsigned	frequency;
 
 	SmoothRefresh  *smooth_refresh;

Modified: trunk/src/proctable.cpp
==============================================================================
--- trunk/src/proctable.cpp	(original)
+++ trunk/src/proctable.cpp	Sat Apr  5 17:50:45 2008
@@ -53,6 +53,8 @@
 #include "interface.h"
 #include "selinux.h"
 
+
+ProcInfo::UserMap ProcInfo::users;
 ProcInfo::List ProcInfo::all;
 std::map<pid_t, guint64> ProcInfo::cpu_times;
 
@@ -445,28 +447,34 @@
 
 
 
-static void
-get_process_user(ProcData* procdata, ProcInfo* info, uid_t uid)
+void
+ProcInfo::set_user(guint uid)
 {
-	struct passwd* pwd;
-	char* username;
-
-	if(G_LIKELY(info->uid == uid))
+	if (G_LIKELY(this->uid == uid))
 		return;
 
-	info->uid = uid;
+	this->uid = uid;
 
-	pwd = getpwuid(uid);
+	typedef std::pair<ProcInfo::UserMap::iterator, bool> Pair;
+	ProcInfo::UserMap::value_type hint(uid, "");
+	Pair p(ProcInfo::users.insert(hint));
 
-	if(pwd && pwd->pw_name)
-		username = g_strdup(pwd->pw_name);
-	else
-		username = g_strdup_printf("%u", (unsigned)uid);
+	// procman_debug("User lookup for uid %u: %s", uid, (p.second ? "MISS" : "HIT"));
+
+	if (p.second) {
+		char* username;
+		struct passwd* pwd;
+		pwd = getpwuid(uid);
 
-	/* don't free, because info->user belongs to procdata->users */
-	info->user = g_string_chunk_insert_const(procdata->users, username);
+		if (pwd && pwd->pw_name)
+			username = g_strdup(pwd->pw_name);
+		else
+			username = g_strdup_printf("%u", uid);
+
+		p.first->second = username;
+	}
 
-	g_free(username);
+	this->user = p.first->second;
 }
 
 
@@ -642,7 +650,7 @@
 
 	get_process_memory_info(info);
 
-	get_process_user(procdata, info, procstate.uid);
+	info->set_user(procstate.uid);
 
 	info->pcpu = (proctime.rtime - info->cpu_time) * 100 / procdata->cpu_total_time;
 	info->pcpu = MIN(info->pcpu, 100);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]