Mercurial > ecos-v3_0-branch
diff packages/kernel/current/src/common/clock.cxx @ 2:443894e2e912 ecos-v1_2_1-release
Block commit of eCos version 1.2.1
| author | jlarmour |
|---|---|
| date | Tue, 11 May 1999 12:24:34 +0000 |
| parents | 3111d98ba7b3 |
| children | 7253dcc42a09 |
line wrap: on
line diff
--- a/packages/kernel/current/src/common/clock.cxx +++ b/packages/kernel/current/src/common/clock.cxx @@ -1,8 +1,8 @@ //========================================================================== // -// common/clock.cxx +// common/clock.cxx // -// Clock class implementations +// Clock class implementations // //========================================================================== //####COPYRIGHTBEGIN#### @@ -22,17 +22,17 @@ // September 30, 1998. // // The Initial Developer of the Original Code is Cygnus. Portions created -// by Cygnus are Copyright (C) 1998 Cygnus Solutions. All Rights Reserved. +// by Cygnus are Copyright (C) 1998,1999 Cygnus Solutions. All Rights Reserved. // ------------------------------------------- // //####COPYRIGHTEND#### //========================================================================== //#####DESCRIPTIONBEGIN#### // -// Author(s): nickg -// Contributors: nickg -// Date: 1997-09-15 -// Purpose: Clock class implementation +// Author(s): nickg +// Contributors: nickg +// Date: 1997-09-15 +// Purpose: Clock class implementation // Description: This file contains the definitions of the counter, // clock and alarm class member functions that are common // to all clock implementations. @@ -107,7 +107,7 @@ Cyg_Counter::~Cyg_Counter() #ifdef CYGDBG_USE_ASSERTS -bool Cyg_Counter::check_this( cyg_assert_class_zeal zeal) +bool Cyg_Counter::check_this( cyg_assert_class_zeal zeal) const { // check that we have a non-NULL pointer first if( this == NULL ) return false; @@ -174,6 +174,11 @@ void Cyg_Counter::tick( cyg_uint32 ticks // Now that we have the list pointer, we can use common code for // both list oragnizations. +#ifdef CYGIMP_KERNEL_COUNTERS_SORT_LIST + + // With a sorted alarm list, we can simply pick alarms off the + // front of the list until we find one that is in the future. + while( *alarm_list_ptr != NULL ) { Cyg_Alarm *alarm = *alarm_list_ptr; @@ -204,7 +209,71 @@ void Cyg_Counter::tick( cyg_uint32 ticks } else break; } +#else + // With an unsorted list, we must scan the whole list for + // candidates. We move the whole list to a temporary location + // before doing this so that we are not disturbed by new + // alarms being added to the list. As we consider and + // eliminate alarms we put them onto the done_list and at the + // end we then move it back to where it belongs. + + Cyg_Alarm *done_list = NULL; + + Cyg_Alarm *alarm_list = *alarm_list_ptr; + *alarm_list_ptr = NULL; + + while( alarm_list != NULL ) + { + Cyg_Alarm *alarm = alarm_list; + + CYG_ASSERTCLASS(alarm, "Bad alarm in counter list" ); + + // remove alarm from list + alarm_list = alarm->next; + + if( alarm->trigger <= counter ) + { + if( alarm->interval != 0 ) + { + // The alarm has a retrigger interval. + // Reset the trigger time and requeue + // the alarm. + alarm->trigger += alarm->interval; + add_alarm( alarm ); + } + else alarm->enabled = false; + + CYG_INSTRUMENT_ALARM( CALL, this, alarm ); + + // call alarm function + alarm->alarm(alarm, alarm->data); + + // all done, loop + } + else + { + // add unused alarm to done list. + alarm->next = done_list; + done_list = alarm; + } + } + + // Transfer any alarms that might have been added to the + // alarm list by alarm callbacks to the done list. This + // happens very rarely. + while( *alarm_list_ptr != NULL ) + { + Cyg_Alarm *alarm = *alarm_list_ptr; + *alarm_list_ptr = alarm->next; + alarm->next = done_list; + done_list = alarm; + } + + // return done list to real list + *alarm_list_ptr = done_list; + +#endif Cyg_Scheduler::unlock(); } @@ -287,7 +356,8 @@ void Cyg_Counter::add_alarm( Cyg_Alarm * #error "No CYGIMP_KERNEL_COUNTERS_x_LIST config" #endif - +#ifdef CYGIMP_KERNEL_COUNTERS_SORT_LIST + // Now that we have the list pointer, we can use common code for // both list oragnizations. @@ -304,7 +374,7 @@ void Cyg_Counter::add_alarm( Cyg_Alarm * if( list_alarm->trigger > alarm->trigger ) break; else alarm_list_ptr = &list_alarm->next; } - +#endif // Insert the new alarm at *alarm_list_ptr alarm->next = *alarm_list_ptr; @@ -393,7 +463,7 @@ Cyg_Clock::~Cyg_Clock() #ifdef CYGDBG_USE_ASSERTS -bool Cyg_Clock::check_this( cyg_assert_class_zeal zeal) +bool Cyg_Clock::check_this( cyg_assert_class_zeal zeal) const { // check that we have a non-NULL pointer first if( this == NULL ) return false; @@ -456,7 +526,7 @@ Cyg_Alarm::~Cyg_Alarm() #ifdef CYGDBG_USE_ASSERTS -bool Cyg_Alarm::check_this( cyg_assert_class_zeal zeal) +bool Cyg_Alarm::check_this( cyg_assert_class_zeal zeal) const { // check that we have a non-NULL pointer first if( this == NULL ) return false; @@ -577,7 +647,7 @@ Cyg_RealTimeClock Cyg_RealTimeClock::rtc Cyg_RealTimeClock::Cyg_RealTimeClock() : Cyg_Clock(rtc_resolution), - interrupt(CYG_VECTOR_RTC, 1, (CYG_ADDRWORD)this, isr, dsr) + interrupt(CYGNUM_HAL_INTERRUPT_RTC, 1, (CYG_ADDRWORD)this, isr, dsr) { CYG_REPORT_FUNCTION(); @@ -585,22 +655,44 @@ Cyg_RealTimeClock::Cyg_RealTimeClock() interrupt.attach(); - interrupt.unmask_interrupt(CYG_VECTOR_RTC); + interrupt.unmask_interrupt(CYGNUM_HAL_INTERRUPT_RTC); Cyg_Clock::real_time_clock = this; } +#ifdef HAL_CLOCK_LATENCY +cyg_tick_count total_clock_latency, total_clock_interrupts; +cyg_int32 min_clock_latency = 0x7FFFFFFF; +cyg_int32 max_clock_latency = 0; +bool measure_clock_latency = false; +#endif + // ------------------------------------------------------------------------- cyg_uint32 Cyg_RealTimeClock::isr(cyg_vector vector, CYG_ADDRWORD data) { // CYG_REPORT_FUNCTION(); +#ifdef HAL_CLOCK_LATENCY + if (measure_clock_latency) { + cyg_int32 delta; + HAL_CLOCK_LATENCY(&delta); + // Note: Ignore a latency of 0 when finding min_clock_latency. + if (delta > 0) { + // Valid delta measured + total_clock_latency += delta; + total_clock_interrupts++; + if (min_clock_latency > delta) min_clock_latency = delta; + if (max_clock_latency < delta) max_clock_latency = delta; + } + } +#endif + CYG_INSTRUMENT_CLOCK( ISR, 0, 0); - HAL_CLOCK_RESET( CYG_VECTOR_RTC, CYGNUM_KERNEL_COUNTERS_RTC_PERIOD ); + HAL_CLOCK_RESET( CYGNUM_HAL_INTERRUPT_RTC, CYGNUM_KERNEL_COUNTERS_RTC_PERIOD ); - Cyg_Interrupt::acknowledge_interrupt(CYG_VECTOR_RTC); + Cyg_Interrupt::acknowledge_interrupt(CYGNUM_HAL_INTERRUPT_RTC); return Cyg_Interrupt::CALL_DSR; }
