Index: cdl/interrupts.cdl =================================================================== RCS file: /cvs/ecos/ecos/packages/kernel/current/cdl/interrupts.cdl,v retrieving revision 1.4 diff -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 -u -r1.11 intr.hxx --- include/intr.hxx 23 May 2002 23:06:47 -0000 1.11 +++ include/intr.hxx 3 Apr 2006 14:30:19 -0000 @@ -187,6 +187,7 @@ CYGBLD_ANNOTATE_VARIABLE_INTR; #endif + #ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_LIST // Number of DSR posts made @@ -198,6 +199,22 @@ // static list of pending DSRs static Cyg_Interrupt* volatile dsr_list[CYGNUM_KERNEL_CPU_MAX] CYGBLD_ANNOTATE_VARIABLE_INTR; + +#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_head[CYGNUM_KERNEL_CPU_MAX] + CYGBLD_ANNOTATE_VARIABLE_INTR; + static Cyg_Interrupt* volatile dsr_list_tail[CYGNUM_KERNEL_CPU_MAX] + CYGBLD_ANNOTATE_VARIABLE_INTR; #endif @@ -363,6 +380,12 @@ return dsr_list[cpu] != NULL; #endif + +#ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_FIFO + + return dsr_list_head[cpu] != NULL; + +#endif }; #endif // CYGIMP_KERNEL_INTERRUPTS_DSRS Index: include/kapidata.h =================================================================== RCS file: /cvs/ecos/ecos/packages/kernel/current/include/kapidata.h,v retrieving revision 1.13 diff -u -r1.13 kapidata.h --- include/kapidata.h 27 Feb 2003 06:14:32 -0000 1.13 +++ include/kapidata.h 4 Apr 2006 11:28:59 -0000 @@ -148,6 +148,10 @@ cyg_ucount32 dsr_count; cyg_interrupt *next_dsr; #endif +#ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_FIFO + cyg_ucount32 dsr_count; + cyg_interrupt *next_dsr; +#endif #ifdef CYGIMP_KERNEL_INTERRUPTS_CHAIN cyg_interrupt *next; #endif Index: src/intr/intr.cxx =================================================================== RCS file: /cvs/ecos/ecos/packages/kernel/current/src/intr/intr.cxx,v retrieving revision 1.17 diff -u -r1.17 intr.cxx --- src/intr/intr.cxx 23 May 2002 23:06:54 -0000 1.17 +++ src/intr/intr.cxx 4 Apr 2006 16:57:20 -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_head[CYGNUM_KERNEL_CPU_MAX]; +Cyg_Interrupt* volatile Cyg_Interrupt::dsr_list_tail[CYGNUM_KERNEL_CPU_MAX]; + +#endif + // ------------------------------------------------------------------------- // Call any pending DSRs @@ -192,6 +206,38 @@ } #endif + +#ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_FIFO + + cyg_uint32 old_intr; + HAL_DISABLE_INTERRUPTS(old_intr); + while( dsr_list_head[cpu] != NULL ) + { + Cyg_Interrupt* intr; + cyg_count32 count; + + + intr = dsr_list_head[cpu]; + dsr_list_head[cpu] = intr->next_dsr; + count = intr->dsr_count; + intr->dsr_count = 0; + intr->next_dsr = 0; + if (dsr_list_head[cpu] == NULL) + { + dsr_list_tail[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 }; @@ -256,6 +302,27 @@ } #endif + +#ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_FIFO + + // Check if this is the first DSR to call. If yes, initialize the + // dsr_list_head, else attach the current irq to the dsr_list_tail. + + if( dsr_count++ == 0 ) + { + Cyg_Interrupt* cur_last_dsr = dsr_list_tail[cpu]; + if (cur_last_dsr != 0) + { + cur_last_dsr->next_dsr = this; + } + else + { + dsr_list_head[cpu] = this; + } + dsr_list_tail[cpu] = this; + } + +#endif HAL_RESTORE_INTERRUPTS(old_intr); }; @@ -282,6 +349,10 @@ ) { // CYG_REPORT_FUNCTION(); + if (intr == 0) + { + diag_printf("ERROR: zero interrupt: %d,0x%08x,0x%08x\n",isr_ret,(unsigned int) intr,(unsigned int) regs); + } #ifdef CYGPKG_KERNEL_SMP_SUPPORT Cyg_Scheduler::lock();