2005-04-16 Andrew J. Schorr <ajschorr@alumni.princeton.edu>

	* configure.ac: Added AC_ARG_ENABLE(time-check).  By default,
	  warning messages will now be printed for threads or commands that take
	  longer than 5 seconds, but this configure argument can be used
	  to disable the checks or change the threshold.
	* thread.h (thread_consumed_time): Declare new function to calculate
	  elapsed microseconds.
	* thread.c (thread_consumed_time): Must be global not static so we
	  can call it from lib/vty.c:vty_command.
	  (thread_should_yield): Surround with `#if 0' to make clear that this
	  function is not currently being used anywhere.
	  (thread_call): If CONSUMED_TIME_CHECK is defined, print a CPU HOG
	  warning message if the thread takes more than CONSUMED_TIME_CHECK
	  microseconds.
	* vty.c (vty_command): If CONSUMED_TIME_CHECK is defined, print a CPU
	  HOG warning message if the command takes more than CONSUMED_TIME_CHECK
	  microseconds.
diff --git a/lib/ChangeLog b/lib/ChangeLog
index e5ee549..d832849 100644
--- a/lib/ChangeLog
+++ b/lib/ChangeLog
@@ -1,3 +1,18 @@
+2005-04-16 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
+
+	* thread.h (thread_consumed_time): Declare new function to calculate
+	  elapsed microseconds.
+	* thread.c (thread_consumed_time): Must be global not static so we
+	  can call it from lib/vty.c:vty_command.
+	  (thread_should_yield): Surround with `#if 0' to make clear that this
+	  function is not currently being used anywhere.
+	  (thread_call): If CONSUMED_TIME_CHECK is defined, print a CPU HOG
+	  warning message if the thread takes more than CONSUMED_TIME_CHECK
+	  microseconds.
+	* vty.c (vty_command): If CONSUMED_TIME_CHECK is defined, print a CPU
+	  HOG warning message if the command takes more than CONSUMED_TIME_CHECK
+	  microseconds.
+
 2005-04-16 Paul Jakma <paul@dishone.st>
 
 	* memtypes.c: the comment about use of comments in the comments
diff --git a/lib/thread.c b/lib/thread.c
index 05212d8..d1c925c 100644
--- a/lib/thread.c
+++ b/lib/thread.c
@@ -804,7 +804,7 @@
     }
 }
 
-static unsigned long
+unsigned long
 thread_consumed_time (RUSAGE_T *now, RUSAGE_T *start)
 {
   unsigned long thread_time;
@@ -821,6 +821,10 @@
   return thread_time;
 }
 
+#if 0
+
+/* This function is not currently used: threads never yield! */
+
 /* We should aim to yield after THREAD_YIELD_TIME_SLOT
    milliseconds.  */
 int
@@ -836,6 +840,8 @@
     return 0;
 }
 
+#endif
+
 /* We check thread consumed time. If the system has getrusage, we'll
    use that to get indepth stats on the performance of the thread.  If
    not - we'll use gettimeofday for some guestimation.  */
@@ -864,20 +870,20 @@
   ++cpu->total_calls;
   cpu->types |= (1 << thread->add_type);
 
-#ifdef THREAD_CONSUMED_TIME_CHECK
-  if (thread_time > 200000L)
+#ifdef CONSUMED_TIME_CHECK
+  if (thread_time > CONSUMED_TIME_CHECK)
     {
       /*
        * We have a CPU Hog on our hands.
        * Whinge about it now, so we're aware this is yet another task
        * to fix.
        */
-      zlog_err ("CPU HOG task %s (%lx) ran for %ldms",
-		thread->funcname,
-		(unsigned long) thread->func,
-		thread_time / 1000L);
+      zlog_warn ("CPU HOG: task %s (%lx) ran for %ldms",
+		 thread->funcname,
+		 (unsigned long) thread->func,
+		 thread_time / 1000L);
     }
-#endif /* THREAD_CONSUMED_TIME_CHECK */
+#endif /* CONSUMED_TIME_CHECK */
 }
 
 /* Execute thread */
diff --git a/lib/thread.h b/lib/thread.h
index 716a6a6..4008ba7 100644
--- a/lib/thread.h
+++ b/lib/thread.h
@@ -158,4 +158,6 @@
 
 extern struct cmd_element show_thread_cpu_cmd;
 
+extern unsigned long thread_consumed_time(RUSAGE_T *after, RUSAGE_T *before);
+
 #endif /* _ZEBRA_THREAD_H */
diff --git a/lib/vty.c b/lib/vty.c
index 600c9fd..ea74172 100644
--- a/lib/vty.c
+++ b/lib/vty.c
@@ -395,8 +395,25 @@
   if (vline == NULL)
     return CMD_SUCCESS;
 
+#ifdef CONSUMED_TIME_CHECK
+  {
+    RUSAGE_T before;
+    RUSAGE_T after;
+    unsigned long cmdtime;
+
+    GETRUSAGE(&before);
+#endif /* CONSUMED_TIME_CHECK */
+
   ret = cmd_execute_command (vline, vty, NULL, 0);
 
+#ifdef CONSUMED_TIME_CHECK
+    GETRUSAGE(&after);
+    if ((cmdtime = thread_consumed_time(&after, &before)) > CONSUMED_TIME_CHECK)
+      /* Warn about CPU hog that must be fixed. */
+      zlog_warn("CPU HOG: command took %lums: %s", cmdtime/1000, buf);
+  }
+#endif /* CONSUMED_TIME_CHECK */
+
   if (ret != CMD_SUCCESS)
     switch (ret)
       {