2005-04-22 Paul Jakma <paul.jakma@sun.com>

	* thread.h: Add background thread type and thread_add_background
	  macro and accompanying funcname_... function.
	  export thread_should_yield, background threads can use it.
	  Lower thread yield time to 10ms, 100ms is noticeable lag and
	  a thread would only be /starting/ to finish sometime afterward.
	* thread.c: (general) Add background thread type and schedule
	  nearly all thread types through the ready list for fairness.
	  (timeval_adjust) static qualifier missing
	  (vty_out_cpu_thread_history) add support for printout of
	  background threads
	  (show_thread_cpu) ditto.
	  (thread_master_debug) add debug of background list
	  (thread_master_create) fixup long line
	  (thread_add_unuse) add asserts for required state.
	  (thread_master_free) free background thread list
	  (funcname_thread_add_timer_timeval) make generic, able to
	  support arbitrary timer-like thread types.
	  (funcname_thread_add_timer) pass thread type to .._add_timer_timeval
	  (funcname_thread_add_timer_msec) ditto
	  (funcname_thread_add_background) Add a background thread, with an
	  optional millisecond delay factor, using .._add_timer_timeval.
	  (thread_cancel) Add background thread type.
	  Move the thread_list_delete common to all cases to bottom of
	  function, after the switch statement..
	  (thread_cancel_event) indent
	  (thread_timer_wait) Static qualifier, and make it able to cope
	  with arbitrary timer-like thread lists, so its of use to
	  background threads too.
	  (thread_process_fd) static qualifier. Again, make it take a list
	  reference rather than thread_master. Fix indentation.
	  (thread_timer_process) Check for ready timer-like threads in the
	  given list and move them on to the ready list - code originally
	  embedded in thread_fetch.
	  (thread_fetch) Schedule all threads, other than events, through
	  the ready list, to ensure fairness. Timer readying code moved to
	  thread_timer_process so it can be reused for background threads.
	  Remove the unneeded quagga_sigevent_process, as pointed out by
	  John Lin <john.ch.lin@gmail.com>.
	  (thread_should_yield) make this available.
diff --git a/lib/thread.h b/lib/thread.h
index 4008ba7..8f683c8 100644
--- a/lib/thread.h
+++ b/lib/thread.h
@@ -47,6 +47,7 @@
   struct thread_list event;
   struct thread_list ready;
   struct thread_list unuse;
+  struct thread_list background;
   fd_set readfd;
   fd_set writefd;
   fd_set exceptfd;
@@ -57,8 +58,8 @@
 struct thread
 {
   unsigned char type;		/* thread type */
-  unsigned char add_type;	/* thread type */
-  struct thread *next;		/* next pointer of the thread */
+  unsigned add_type;		/* thread type */
+  struct thread *next;		/* next pointer of the thread */   
   struct thread *prev;		/* previous pointer of the thread */
   struct thread_master *master;	/* pointer to the struct thread_master. */
   int (*func) (struct thread *); /* event function */
@@ -72,7 +73,7 @@
   char* funcname;
 };
 
-struct cpu_thread_history {
+struct cpu_thread_history  {
   int (*func)(struct thread *);
   const char *funcname;
   unsigned int total_calls;
@@ -86,11 +87,12 @@
 #define THREAD_TIMER          2
 #define THREAD_EVENT          3
 #define THREAD_READY          4
-#define THREAD_UNUSED         5
-#define THREAD_EXECUTE        6
+#define THREAD_BACKGROUND     5
+#define THREAD_UNUSED         6
+#define THREAD_EXECUTE        7
 
 /* Thread yield time.  */
-#define THREAD_YIELD_TIME_SLOT     100 * 1000L /* 100ms */
+#define THREAD_YIELD_TIME_SLOT     10 * 1000L /* 100ms */
 
 /* Macros. */
 #define THREAD_ARG(X) ((X)->arg)
@@ -134,6 +136,7 @@
 #define thread_add_timer_msec(m,f,a,v) funcname_thread_add_timer_msec(m,f,a,v,#f)
 #define thread_add_event(m,f,a,v) funcname_thread_add_event(m,f,a,v,#f)
 #define thread_execute(m,f,a,v) funcname_thread_execute(m,f,a,v,#f)
+#define thread_add_background(m,f,a,v) funcname_thread_add_background(m,f,a,v,#f)
 
 /* Prototypes. */
 struct thread_master *thread_master_create ();
@@ -147,6 +150,11 @@
 				 int (*)(struct thread *), void *, long, const char*);
 struct thread *funcname_thread_add_event (struct thread_master *,
 				 int (*)(struct thread *), void *, int, const char*);
+struct thread *funcname_thread_add_background (struct thread_master *,
+				               int (*)(struct thread *),
+				               void *, 
+				               long, const char*);
+
 void thread_cancel (struct thread *);
 void thread_cancel_event (struct thread_master *, void *);
 
@@ -155,8 +163,10 @@
 			       int (*)(struct thread *), void *, int, const char *);
 void thread_call (struct thread *);
 unsigned long thread_timer_remain_second (struct thread *);
+int thread_should_yield (struct thread *);
 
 extern struct cmd_element show_thread_cpu_cmd;
+extern struct cmd_element show_thread_work_queues_cmd;
 
 extern unsigned long thread_consumed_time(RUSAGE_T *after, RUSAGE_T *before);