[lib] Optimise thread_call by caching pointer to thread history in the thread

2006-07-25 Paul Jakma <paul.jakma@sun.com>

	* thread.h: (struct thread) Add a cache pointer to the struct
	  cpu_thread_history, if it is known - saving hash lookup on
	  each thread_call.
	* thread.c: (thread_call) Cache the pointer to the
          cpu_thread_history, so that future thread_calls of same
          thread can avoid the hash_lookup.
diff --git a/lib/ChangeLog b/lib/ChangeLog
index 0214867..7a74439 100644
--- a/lib/ChangeLog
+++ b/lib/ChangeLog
@@ -1,3 +1,12 @@
+2006-07-25 Paul Jakma <paul.jakma@sun.com>
+
+	* thread.h: (struct thread) Add a cache pointer to the struct
+	  cpu_thread_history, if it is known - saving hash lookup on
+	  each thread_call.
+	* thread.c: (thread_call) Cache the pointer to the
+          cpu_thread_history, so that future thread_calls of same
+          thread can avoid the hash_lookup.
+
 2006-07-10 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
 
 	* vty.c: (vty_log_out) Do not call vty_close, because this could
diff --git a/lib/thread.c b/lib/thread.c
index 32fc15e..8b6a7e2 100644
--- a/lib/thread.c
+++ b/lib/thread.c
@@ -879,12 +879,23 @@
 {
   unsigned long realtime, cputime;
   RUSAGE_T ru;
-  struct cpu_thread_history tmp, *cpu;
-  
-  tmp.func = thread->func;
-  tmp.funcname = thread->funcname;
-  cpu = hash_get (cpu_record, &tmp, 
-                  (void * (*) (void *))cpu_record_hash_alloc);
+
+ /* Cache a pointer to the relevant cpu history thread, if the thread
+  * does not have it yet.
+  *
+  * Callers submitting 'dummy threads' hence must take care that
+  * thread->cpu is NULL
+  */
+  if (!thread->hist)
+    {
+      struct cpu_thread_history tmp;
+      
+      tmp.func = thread->func;
+      tmp.funcname = thread->funcname;
+      
+      thread->hist = hash_get (cpu_record, &tmp, 
+                    (void * (*) (void *))cpu_record_hash_alloc);
+    }
 
   GETRUSAGE (&thread->ru);
 
@@ -893,17 +904,17 @@
   GETRUSAGE (&ru);
 
   realtime = thread_consumed_time (&ru, &thread->ru, &cputime);
-  cpu->real.total += realtime;
-  if (cpu->real.max < realtime)
-    cpu->real.max = realtime;
+  thread->hist->real.total += realtime;
+  if (thread->hist->real.max < realtime)
+    thread->hist->real.max = realtime;
 #ifdef HAVE_RUSAGE
-  cpu->cpu.total += cputime;
-  if (cpu->cpu.max < cputime)
-    cpu->cpu.max = cputime;
+  thread->hist->cpu.total += cputime;
+  if (thread->hist->cpu.max < cputime)
+    thread->hist->cpu.max = cputime;
 #endif
 
-  ++cpu->total_calls;
-  cpu->types |= (1 << thread->add_type);
+  ++(thread->hist->total_calls);
+  thread->hist->types |= (1 << thread->add_type);
 
 #ifdef CONSUMED_TIME_CHECK
   if (realtime > CONSUMED_TIME_CHECK)
diff --git a/lib/thread.h b/lib/thread.h
index f693ff5..0670a89 100644
--- a/lib/thread.h
+++ b/lib/thread.h
@@ -80,6 +80,7 @@
     struct timeval sands;	/* rest of time sands value. */
   } u;
   RUSAGE_T ru;			/* Indepth usage info.  */
+  struct cpu_thread_history *hist; /* cache pointer to cpu_history */
   char* funcname;
 };