Index: cpukit/ChangeLog
===================================================================
--- cpukit/ChangeLog	(revision cd62f7a7fd0f4c5cd416f9529f698a4c7cf2cee4)
+++ cpukit/ChangeLog	(revision 24399ad594339a1e2e14df1daec680dbe57cb8e5)
@@ -1,2 +1,7 @@
+2009-07-24	Joel Sherrill <joel.sherrill@OARcorp.com>
+
+	* posix/src/killinfo.c: Rework to make easier to analyze for code
+	coverage and to simplify so it is easier to analyze for correctness.
+
 2009-07-24	Roxana Leontie <roxana.leontie@gmail.com>
 
Index: cpukit/posix/src/killinfo.c
===================================================================
--- cpukit/posix/src/killinfo.c	(revision cd62f7a7fd0f4c5cd416f9529f698a4c7cf2cee4)
+++ cpukit/posix/src/killinfo.c	(revision 24399ad594339a1e2e14df1daec680dbe57cb8e5)
@@ -26,6 +26,20 @@
 #include <rtems/score/isr.h>
 
-/*PAGE
- *
+/*
+ *  If you enable this, then you get printk() feedback on each path
+ *  and the input to the decision that lead to the decision.  Hopefully
+ *  this will help in debugging the algorithm that distributes process
+ *  signals to individual threads.
+ */
+
+/* #define DEBUG_SIGNAL_PROCESSING */
+#if defined(DEBUG_SIGNAL_PROCESSING)
+  #include <rtems/bspIo.h>
+  #define DEBUG_STEP(_x) printk(_x)
+#else
+  #define DEBUG_STEP(_x)
+#endif
+
+/*
  *  3.3.2 Send a Signal to a Process, P1003.1b-1993, p. 68
  *
@@ -50,5 +64,5 @@
   Objects_Control            **object_table;
   Thread_Control              *the_thread;
-  Thread_Control              *interested_thread;
+  Thread_Control              *interested;
   Priority_Control             interested_priority;
   Chain_Control               *the_chain;
@@ -116,34 +130,31 @@
   /*
    *  Is an interested thread waiting for this signal (sigwait())?
+   *
+   *  There is no requirement on the order of threads pending on a sigwait().
    */
 
   /* XXX violation of visibility -- need to define thread queue support */
 
-  for( index=0 ;
-       index < TASK_QUEUE_DATA_NUMBER_OF_PRIORITY_HEADERS ;
-       index++ ) {
-
-    the_chain = &_POSIX_signals_Wait_queue.Queues.Priority[ index ];
-
-    for ( the_node = the_chain->first ;
-          !_Chain_Is_tail( the_chain, the_node ) ;
-          the_node = the_node->next ) {
-
-      the_thread = (Thread_Control *)the_node;
-      api = the_thread->API_Extensions[ THREAD_API_POSIX ];
-
-      /*
-       * Is this thread is actually blocked waiting for the signal?
-       */
-      if (the_thread->Wait.option & mask)
-        goto process_it;
-
-      /*
-       * Is this thread is blocked waiting for another signal but has
-       * not blocked this one?
-       */
-      if (~api->signals_blocked & mask)
-        goto process_it;
-    }
+  the_chain = &_POSIX_signals_Wait_queue.Queues.Fifo;
+
+  for ( the_node = the_chain->first ;
+        !_Chain_Is_tail( the_chain, the_node ) ;
+        the_node = the_node->next ) {
+
+    the_thread = (Thread_Control *)the_node;
+    api = the_thread->API_Extensions[ THREAD_API_POSIX ];
+
+    /*
+     * Is this thread is actually blocked waiting for the signal?
+     */
+    if (the_thread->Wait.option & mask)
+      goto process_it;
+
+    /*
+     * Is this thread is blocked waiting for another signal but has
+     * not blocked this one?
+     */
+    if (~api->signals_blocked & mask)
+      goto process_it;
   }
 
@@ -163,10 +174,8 @@
    *    + rtems internal threads do not receive signals.
    */
-  interested_thread = NULL;
+  interested = NULL;
   interested_priority = PRIORITY_MAXIMUM + 1;
 
-  for ( the_api = OBJECTS_CLASSIC_API;
-        the_api <= OBJECTS_APIS_LAST;
-        the_api++ ) {
+  for (the_api = OBJECTS_CLASSIC_API; the_api <= OBJECTS_APIS_LAST; the_api++) {
 
     /*
@@ -185,5 +194,5 @@
        */
       if ( !the_info )
-	continue;
+        continue;
     #endif
 
@@ -197,4 +206,13 @@
         continue;
 
+      #if defined(DEBUG_SIGNAL_PROCESSING)
+        printk("\n 0x%08x/0x%08x %d/%d 0x%08x 1",
+          the_thread->Object.id, 
+          ((interested) ? interested->Object.id : 0), 
+          the_thread->current_priority, interested_priority,
+          the_thread->current_state
+        );
+      #endif
+
       /*
        *  If this thread is of lower priority than the interested thread,
@@ -203,4 +221,5 @@
       if ( the_thread->current_priority > interested_priority )
         continue;
+      DEBUG_STEP("2");
 
       /*
@@ -216,14 +235,5 @@
       if ( !_POSIX_signals_Is_interested( api, mask ) )
         continue;
-
-      /*
-       *  If we have not seen a thread interested in this signal yet,
-       *  then we have found the first one.
-       */
-      if ( !interested_thread ) {
-        interested_thread   = the_thread;
-        interested_priority = the_thread->current_priority;
-        continue;
-      }
+      DEBUG_STEP("3");
 
       /*
@@ -231,52 +241,50 @@
        *  If the thread under consideration is of higher priority, then
        *  it becomes the interested thread.
+       *
+       *  NOTE: We initialized interested_priority to PRIORITY_MAXIMUM + 1
+       *        so we never have to worry about deferencing a NULL
+       *        interested thread.
        */
       if ( the_thread->current_priority < interested_priority ) {
-        interested_thread   = the_thread;
+        interested   = the_thread;
         interested_priority = the_thread->current_priority;
         continue;
       }
+      DEBUG_STEP("4");
 
       /*
        *  Now the thread and the interested thread have the same priority.
-       *  If the interested thread is ready, then we don't need to send it
-       *  to a blocked thread.
-       */
-      if ( _States_Is_ready( interested_thread->current_state ) )
-        continue;
-
-      /*
-       *  Now the interested thread is blocked.
-       *  If the thread we are considering is not, the it becomes the
-       *  interested thread.
-       */
-      if ( _States_Is_ready( the_thread->current_state ) ) {
-        interested_thread   = the_thread;
-        interested_priority = the_thread->current_priority;
-        continue;
-      }
-
-      /*
-       *  Now we know both threads are blocked.
-       *  If the interested thread is interruptible, then just use it.
-       */
-      if (_States_Is_interruptible_by_signal(interested_thread->current_state))
-        continue;
-
-      /*
-       *  Now both threads are blocked and the interested thread is not
-       *  interruptible.
-       *  If the thread under consideration is interruptible by a signal,
-       *  then it becomes the interested thread.
-       */
-      if ( _States_Is_interruptible_by_signal(the_thread->current_state) ) {
-        interested_thread   = the_thread;
-        interested_priority = the_thread->current_priority;
+       *  We have to sort through the combinations of blocked/not blocked
+       *  and blocking interruptibutable by signal.
+       *
+       *  If the interested thread is ready, don't think about changing.
+       */
+
+      if ( !_States_Is_ready( interested->current_state ) ) {
+        /* preferred ready over blocked */
+        DEBUG_STEP("5");
+        if ( _States_Is_ready( the_thread->current_state ) ) {
+          interested          = the_thread;
+          interested_priority = the_thread->current_priority;
+          continue;
+        }
+ 
+        DEBUG_STEP("6");
+        /* prefer blocked/interruptible over blocked/not interruptible */
+        if ( !_States_Is_interruptible_by_signal(interested->current_state) ) {
+          DEBUG_STEP("7");
+          if ( _States_Is_interruptible_by_signal(the_thread->current_state) ) {
+            DEBUG_STEP("8");
+            interested          = the_thread;
+            interested_priority = the_thread->current_priority;
+            continue;
+          }
+        }
       }
     }
   }
 
-  if ( interested_thread ) {
-    the_thread = interested_thread;
+  if ( interested ) {
+    the_thread = interested;
     goto process_it;
   }
@@ -333,4 +341,5 @@
   }
 
+  DEBUG_STEP("\n");
   _Thread_Enable_dispatch();
   return 0;
