Mercurial > ecos
changeset 2266:13625e7b9d1f
Implement FIFO variant of scheduling of DSRs and make it the
default. This is reworked patch originally suggested by Stefan
Sommerfeld <sommerfeld@mikrom.com>.
* cdl/interrupts.cdl (CYGIMP_KERNEL_INTERRUPTS_DSRS_LIST): make it
cdl_component.
* cdl/interrupts.cdl (CYGSEM_KERNEL_INTERRUPTS_DSRS_LIST_FIFO):
new option for CYGIMP_KERNEL_INTERRUPTS_DSRS_LIST.
* include/intr.hxx (class Cyg_Interrupt): new static variable
dsr_list_tail.
* src/intr/intr.cxx (call_pending_DSRs_inner): add
CYGSEM_KERNEL_INTERRUPTS_DSRS_LIST_FIFO variant.
(post_dsr): likewise.
* tests/intr0.cxx: fix comments to match actual option names.
* tests/kintr0.c: likewise.2006-03-27 Marco Cruz <marco@daruma.com.br>
| author | nickg |
|---|---|
| date | Fri, 11 Aug 2006 09:29:31 +0000 |
| parents | b5670f3c40f2 |
| children | ce8216bec66a |
| files | packages/hal/sh/arch/current/src/context.S packages/kernel/current/ChangeLog packages/kernel/current/cdl/interrupts.cdl packages/kernel/current/include/intr.hxx packages/kernel/current/src/intr/intr.cxx packages/kernel/current/tests/intr0.cxx packages/kernel/current/tests/kintr0.c |
| diffstat | 7 files changed, 115 insertions(+), 16 deletions(-) [+] |
line wrap: on
line diff
--- a/packages/hal/sh/arch/current/src/context.S +++ b/packages/hal/sh/arch/current/src/context.S @@ -240,11 +240,11 @@ FUNC_START(hal_thread_load_context) lds.l @r0+,pr ! pr - mov r3,r15 ! update stack pointer - mov.l @r0+,r2 ! SR hal_cpu_int_merge r2,r0,r1 ! restore interrupt state + mov r3,r15 ! update stack pointer + rts ! and return nop
--- a/packages/kernel/current/ChangeLog +++ b/packages/kernel/current/ChangeLog @@ -11,6 +11,24 @@ 2006-04-11 Sergei Organov <osv@javad.co * doc/kernel.sgml: Fix typo +2006-04-10 Sergei Organov <osv@javad.com> + + Implement FIFO variant of scheduling of DSRs and make it the + default. This is reworked patch originally suggested by Stefan + Sommerfeld <sommerfeld@mikrom.com>. + + * cdl/interrupts.cdl (CYGIMP_KERNEL_INTERRUPTS_DSRS_LIST): make it + cdl_component. + * cdl/interrupts.cdl (CYGSEM_KERNEL_INTERRUPTS_DSRS_LIST_FIFO): + new option for CYGIMP_KERNEL_INTERRUPTS_DSRS_LIST. + * include/intr.hxx (class Cyg_Interrupt): new static variable + dsr_list_tail. + * src/intr/intr.cxx (call_pending_DSRs_inner): add + CYGSEM_KERNEL_INTERRUPTS_DSRS_LIST_FIFO variant. + (post_dsr): likewise. + * tests/intr0.cxx: fix comments to match actual option names. + * tests/kintr0.c: likewise.2006-03-27 Marco Cruz <marco@daruma.com.br> + 2006-03-27 Marco Cruz <marco@daruma.com.br> * include/thread.hxx: removed extra qualifier of
--- a/packages/kernel/current/cdl/interrupts.cdl +++ b/packages/kernel/current/cdl/interrupts.cdl @@ -74,7 +74,7 @@ cdl_component CYGIMP_KERNEL_INTERRUPTS_D # NOTE: the choice of list vs table should not be two separate # options. There is a single option which must have one of # two legal values. - cdl_option CYGIMP_KERNEL_INTERRUPTS_DSRS_LIST { + cdl_component CYGIMP_KERNEL_INTERRUPTS_DSRS_LIST { display "Use linked lists for DSRs" default_value 1 implements CYGINT_KERNEL_INTERRUPTS_DSRS @@ -85,6 +85,22 @@ cdl_component CYGIMP_KERNEL_INTERRUPTS_D 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." + + cdl_option CYGSEM_KERNEL_INTERRUPTS_DSRS_LIST_FIFO { + display "Schedule DSRs in FIFO order" + flavor bool + default_value 1 + description "When this option is set, DSRs are scheduled + in the natural FIFO (first in, first out) order, + otherwise they are scheduled in LIFO (last in, first + out) order. Applications should not rely on any + particular order of scheduling of DSRs. LIFO + scheduling is kept for backward compatibility only and + is not recommended as it may lead to high (up to 2 + times higher then FIFO) IRQ-to-DSR latencies at some + (typically rare) conditions. If unsure, leave this set." + } + } cdl_component CYGIMP_KERNEL_INTERRUPTS_DSRS_TABLE {
--- a/packages/kernel/current/include/intr.hxx +++ b/packages/kernel/current/include/intr.hxx @@ -195,11 +195,17 @@ class Cyg_Interrupt // next DSR in list Cyg_Interrupt* volatile next_dsr CYGBLD_ANNOTATE_VARIABLE_INTR; - // static list of pending DSRs + // head of static list of pending DSRs static Cyg_Interrupt* volatile dsr_list[CYGNUM_KERNEL_CPU_MAX] CYGBLD_ANNOTATE_VARIABLE_INTR; - -#endif + +# ifdef CYGSEM_KERNEL_INTERRUPTS_DSRS_LIST_FIFO + // tail of static list of pending DSRs + static Cyg_Interrupt* volatile dsr_list_tail[CYGNUM_KERNEL_CPU_MAX] + CYGBLD_ANNOTATE_VARIABLE_INTR; +# endif + +#endif // defined CYGIMP_KERNEL_INTERRUPTS_DSRS_LIST #ifdef CYGIMP_KERNEL_INTERRUPTS_CHAIN
--- a/packages/kernel/current/src/intr/intr.cxx +++ b/packages/kernel/current/src/intr/intr.cxx @@ -137,6 +137,10 @@ volatile cyg_ucount32 Cyg_Interrupt::dsr Cyg_Interrupt* volatile Cyg_Interrupt::dsr_list[CYGNUM_KERNEL_CPU_MAX]; +# ifdef CYGSEM_KERNEL_INTERRUPTS_DSRS_LIST_FIFO +Cyg_Interrupt* volatile Cyg_Interrupt::dsr_list_tail[CYGNUM_KERNEL_CPU_MAX]; +# endif + #endif // ------------------------------------------------------------------------- @@ -170,6 +174,35 @@ Cyg_Interrupt::call_pending_DSRs_inner(v #ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_LIST +# ifdef CYGSEM_KERNEL_INTERRUPTS_DSRS_LIST_FIFO + + cyg_uint32 old_intr; + HAL_DISABLE_INTERRUPTS(old_intr); + Cyg_Interrupt* intr = dsr_list[cpu]; + CYG_ASSERT(intr != 0, "No DSRs are pended"); + dsr_list[cpu] = 0; + dsr_list_tail[cpu] = 0; + while(true) + { + cyg_count32 count = intr->dsr_count; + Cyg_Interrupt* next = intr->next_dsr; + intr->dsr_count = 0; + intr->next_dsr = 0; + HAL_RESTORE_INTERRUPTS(old_intr); + + CYG_ASSERT(intr->dsr != 0, "No DSR defined"); + CYG_ASSERT(count > 0, "DSR posted but post count is zero"); + intr->dsr(intr->vector, count, (CYG_ADDRWORD)intr->data); + + if (!next) + break; + + intr = next; + HAL_DISABLE_INTERRUPTS(old_intr); + } + +# else // ! defined CYGSEM_KERNEL_INTERRUPTS_DSRS_LIST_FIFO + while( dsr_list[cpu] != NULL ) { Cyg_Interrupt* intr; @@ -191,8 +224,10 @@ Cyg_Interrupt::call_pending_DSRs_inner(v } -#endif - +# endif // ! defined CYGSEM_KERNEL_INTERRUPTS_DSRS_LIST_FIFO + +#endif // defined CYGIMP_KERNEL_INTERRUPTS_DSRS_LIST + }; externC void @@ -245,17 +280,39 @@ Cyg_Interrupt::post_dsr(void) // Only add the interrupt to the dsr list if this is // the first DSR call. - // At present DSRs are pushed onto the list and will be - // called in reverse order. We do not define the order - // in which DSRs are called, so this is acceptable. - if( dsr_count++ == 0 ) { +# ifdef CYGSEM_KERNEL_INTERRUPTS_DSRS_LIST_FIFO + + // Add to the tail of the list. + Cyg_Interrupt* tail = dsr_list_tail[cpu]; + dsr_list_tail[cpu] = this; + if( tail ) + { + CYG_ASSERT( 0 != dsr_list[cpu] , + "DSR list is not empty but its head is 0"); + tail->next_dsr = this; + } + else + { + CYG_ASSERT( 0 == dsr_list[cpu] , + "DSR list tail is 0 but its head is not"); + dsr_list[cpu] = this; + } + +# else // ! defined CYGSEM_KERNEL_INTERRUPTS_DSRS_LIST_FIFO + + // At present DSRs are pushed onto the list and will be called + // in reverse order. We do not define the order in which DSRs + // are called, so this is acceptable. next_dsr = dsr_list[cpu]; dsr_list[cpu] = this; + +# endif // ! defined CYGSEM_KERNEL_INTERRUPTS_DSRS_LIST_FIFO + } - -#endif + +#endif // defined CYGIMP_KERNEL_INTERRUPTS_DSRS_LIST HAL_RESTORE_INTERRUPTS(old_intr); };
--- a/packages/kernel/current/tests/intr0.cxx +++ b/packages/kernel/current/tests/intr0.cxx @@ -46,8 +46,9 @@ // Description: Very basic test of interrupt objects // Options: // CYGIMP_KERNEL_INTERRUPTS_DSRS_TABLE -// CYGIMP_KERNEL_INTERRUPTS_DSRS_TABLE_SIZE +// CYGNUM_KERNEL_INTERRUPTS_DSRS_TABLE_SIZE // CYGIMP_KERNEL_INTERRUPTS_DSRS_LIST +// CYGSEM_KERNEL_INTERRUPTS_DSRS_LIST_FIFO //####DESCRIPTIONEND#### #include <pkgconf/kernel.h>
--- a/packages/kernel/current/tests/kintr0.c +++ b/packages/kernel/current/tests/kintr0.c @@ -46,8 +46,9 @@ // Description: Very basic test of interrupt objects // Options: // CYGIMP_KERNEL_INTERRUPTS_DSRS_TABLE -// CYGIMP_KERNEL_INTERRUPTS_DSRS_TABLE_MAX +// CYGNUM_KERNEL_INTERRUPTS_DSRS_TABLE_SIZE // CYGIMP_KERNEL_INTERRUPTS_DSRS_LIST +// CYGSEM_KERNEL_INTERRUPTS_DSRS_LIST_FIFO //####DESCRIPTIONEND#### */
