Index: cdl/interrupts.cdl
===================================================================
RCS file: /cvs/ecos/ecos/packages/kernel/current/cdl/interrupts.cdl,v
retrieving revision 1.4
diff -w -u -r1.4 interrupts.cdl
--- cdl/interrupts.cdl	23 May 2002 23:06:45 -0000	1.4
+++ cdl/interrupts.cdl	15 Feb 2006 13:07:22 -0000
@@ -87,6 +87,21 @@
             possibility of a table overflow occurring."
     }
 
+    cdl_option CYGIMP_KERNEL_INTERRUPTS_DSRS_FIFO {
+        display       "Use FIFO for DSRs "
+        default_value 0
+        implements    CYGINT_KERNEL_INTERRUPTS_DSRS
+        description   "
+            When DSR support is enabled the kernel must keep track of all
+            the DSRs that are pending. This information can be kept in a
+            fixed-size table or in a linked list. The list implementation
+            requires that the kernel disable interrupts for a very short
+            period of time outside interrupt handlers, but there is no
+            possibility of a table overflow occurring. Instead of LIST this
+            implementation processed the DSR and first come, first serve
+            order, which reduces the ISR to DSR delay."
+    }
+
     cdl_component CYGIMP_KERNEL_INTERRUPTS_DSRS_TABLE {
         display       "Use fixed-size table for DSRs"
         default_value 0
Index: include/intr.hxx
===================================================================
RCS file: /cvs/ecos/ecos/packages/kernel/current/include/intr.hxx,v
retrieving revision 1.11
diff -w -u -r1.11 intr.hxx
--- include/intr.hxx	23 May 2002 23:06:47 -0000	1.11
+++ include/intr.hxx	15 Feb 2006 12:41:10 -0000
@@ -187,6 +187,7 @@
                                                CYGBLD_ANNOTATE_VARIABLE_INTR;
 
 #endif
+
 #ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_LIST
 
     // Number of DSR posts made
@@ -201,6 +202,22 @@
     
 #endif
 
+#ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_FIFO
+
+    // Number of DSR posts made
+    volatile cyg_ucount32 dsr_count CYGBLD_ANNOTATE_VARIABLE_INTR; 
+
+    // next DSR in list
+    Cyg_Interrupt* volatile next_dsr CYGBLD_ANNOTATE_VARIABLE_INTR; 
+
+    // static list of pending DSRs
+    static Cyg_Interrupt* volatile dsr_list[CYGNUM_KERNEL_CPU_MAX]
+                                           CYGBLD_ANNOTATE_VARIABLE_INTR;
+    static Cyg_Interrupt* volatile last_dsr[CYGNUM_KERNEL_CPU_MAX]
+                                           CYGBLD_ANNOTATE_VARIABLE_INTR;
+    
+#endif
+
 #ifdef CYGIMP_KERNEL_INTERRUPTS_CHAIN
 
     // The default mechanism for handling interrupts is to attach just
Index: src/intr/intr.cxx
===================================================================
RCS file: /cvs/ecos/ecos/packages/kernel/current/src/intr/intr.cxx,v
retrieving revision 1.17
diff -w -u -r1.17 intr.cxx
--- src/intr/intr.cxx	23 May 2002 23:06:54 -0000	1.17
+++ src/intr/intr.cxx	15 Feb 2006 12:38:38 -0000
@@ -100,6 +100,13 @@
 
 #endif
 
+#ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_FIFO
+
+    dsr_count   = 0;
+    next_dsr    = NULL;
+
+#endif
+
 #ifdef CYGIMP_KERNEL_INTERRUPTS_CHAIN
 
     next        = NULL;
@@ -139,6 +146,13 @@
 
 #endif
 
+#ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_FIFO
+
+Cyg_Interrupt* volatile Cyg_Interrupt::dsr_list[CYGNUM_KERNEL_CPU_MAX];
+Cyg_Interrupt* volatile Cyg_Interrupt::last_dsr[CYGNUM_KERNEL_CPU_MAX];
+
+#endif
+
 // -------------------------------------------------------------------------
 // Call any pending DSRs
 
@@ -193,6 +207,38 @@
     
 #endif
     
+#ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_FIFO
+
+    cyg_uint32 old_intr;
+    HAL_DISABLE_INTERRUPTS(old_intr);
+    while( dsr_list[cpu] != NULL )
+    {
+        Cyg_Interrupt* intr;
+        cyg_count32 count;
+        
+        
+        intr = dsr_list[cpu];
+        dsr_list[cpu] = intr->next_dsr;
+        count = intr->dsr_count;
+        intr->dsr_count = 0;
+        intr->next_dsr = 0;
+        if (dsr_list[cpu] == NULL)
+        {
+            last_dsr[cpu] = NULL;
+        }
+        
+        HAL_RESTORE_INTERRUPTS(old_intr);
+        
+        CYG_ASSERT( intr->dsr != NULL , "No DSR defined");
+
+        intr->dsr( intr->vector, count, (CYG_ADDRWORD)intr->data );
+        
+    	  HAL_DISABLE_INTERRUPTS(old_intr);
+    }
+    HAL_RESTORE_INTERRUPTS(old_intr);
+    
+#endif
+    
 };
 
 externC void
@@ -257,6 +303,27 @@
     
 #endif
     
+#ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_FIFO
+
+    // Only add the interrupt to the dsr list if this is
+    // the first DSR call.
+    
+    if( dsr_count++ == 0 )
+    {
+        Cyg_Interrupt* cur_last_dsr = last_dsr[cpu];
+        if (cur_last_dsr)
+        {
+            cur_last_dsr->next_dsr = this;
+        }
+        else
+        {
+            dsr_list[cpu] = this;
+        }
+        last_dsr[cpu] = this;
+    }
+    
+#endif
+    
     HAL_RESTORE_INTERRUPTS(old_intr);    
 };
 

