On Fri, Dec 9, 2016 at 11:21 AM, Kuan-Hsun Chen <c00...@gmail.com> wrote: > Three additional functions: > RM_Postponed_num, RM_Renew_deadline, and RM_Release_postponedjob. > > Four refined functions: > RM_Activate, RM_Block_while_expired, rtems_rate_monotonic_period, RM_Timeout. > > Rate_monotonic_Control contains one counter for counting the postponed jobs > and one for recording the recent deadline. > --- > cpukit/rtems/include/rtems/rtems/ratemon.h | 42 ++++++-- > cpukit/rtems/include/rtems/rtems/ratemonimpl.h | 25 +++-- > cpukit/rtems/src/ratemonperiod.c | 144 > +++++++++++++++++++++---- > cpukit/rtems/src/ratemontimeout.c | 13 ++- > 4 files changed, 183 insertions(+), 41 deletions(-) > > diff --git a/cpukit/rtems/include/rtems/rtems/ratemon.h > b/cpukit/rtems/include/rtems/rtems/ratemon.h > index 50b8478..71a99dc 100644 > --- a/cpukit/rtems/include/rtems/rtems/ratemon.h > +++ b/cpukit/rtems/include/rtems/rtems/ratemon.h > @@ -22,6 +22,7 @@ > > /* COPYRIGHT (c) 1989-2009, 2016. > * On-Line Applications Research Corporation (OAR). > + * COPYRIGHT (c) 2016 Kuan-Hsun Chen, TU Dortmund University (TUDo). > * > * The license and distribution terms for this file may be > * found in the file LICENSE in this distribution or at > @@ -194,11 +195,6 @@ typedef struct { > /** This field is the object management portion of a Period instance. */ > Objects_Control Object; > > - /** > - * @brief Protects the rate monotonic period state. > - */ > - ISR_LOCK_MEMBER( Lock ) > - Why are these removed?
> /** This is the timer used to provide the unblocking mechanism. */ > Watchdog_Control Timer; > > @@ -206,12 +202,6 @@ typedef struct { > rtems_rate_monotonic_period_states state; > > /** > - * @brief A priority node for use by the scheduler job release and cancel > - * operations. > - */ > - Priority_Node Priority; > - > - /** Ditto. > * This field contains the length of the next period to be > * executed. > */ > @@ -240,6 +230,19 @@ typedef struct { > * This field contains the statistics maintained for the period. > */ > Rate_monotonic_Statistics Statistics; > + > + /** > + * This field contains the number of postponed jobs. When the watchdog > timeout, > + * this variable will be increased immediately. > + */ > + uint32_t postponed_jobs; > + > + /** > + * This field contains the tick of the latest deadline decided by the > period > + * watchdog. > + */ > + uint64_t latest_deadline; > + > } Rate_monotonic_Control; > > /** > @@ -386,6 +389,23 @@ void rtems_rate_monotonic_report_statistics_with_plugin( > void rtems_rate_monotonic_report_statistics( void ); > > /** > + * @brief RTEMS Return the number of postponed jobs remove "RTEMS". > + * > + * This is a helper function to return the number of postponed jobs by this by -> in > + * given period. This number is only increased by the corresponding watchdog, Is it only in a given period, or is it postponed jobs generally, i.e. you could miss multiple periods hence jobs in multiple periods would be counted here? > + * and is decreased by RMS manager with the postponed job releasing. > + * > + * @param[in] id is the period id > + * > + * @retval This helper function returns the number of postponed > + * jobs with given period_id. > + * > + */ > +uint32_t rtems_rate_monotonic_Postponed_num( See coding conventions for naming rules. this is better 'rtems_rate_monotonic_postponed_jobs(). Is this function needed in the public-facing API? > + rtems_id period_id > +); > + > +/** > * @brief RTEMS Rate Monotonic Period > * > * This routine implements the rtems_rate_monotonic_period directive. When > diff --git a/cpukit/rtems/include/rtems/rtems/ratemonimpl.h > b/cpukit/rtems/include/rtems/rtems/ratemonimpl.h > index b6b3ffd..6cdaaeb 100644 > --- a/cpukit/rtems/include/rtems/rtems/ratemonimpl.h > +++ b/cpukit/rtems/include/rtems/rtems/ratemonimpl.h > @@ -9,6 +9,7 @@ > /* COPYRIGHT (c) 1989-2008. > * On-Line Applications Research Corporation (OAR). > * Copyright (c) 2016 embedded brains GmbH. > + * COPYRIGHT (c) 2016 Kuan-Hsun Chen, TU Dortmund University (TUDo). > * > * The license and distribution terms for this file may be > * found in the file LICENSE in this distribution or at > @@ -69,19 +70,19 @@ RTEMS_INLINE_ROUTINE Rate_monotonic_Control > *_Rate_monotonic_Allocate( void ) > } > > RTEMS_INLINE_ROUTINE void _Rate_monotonic_Acquire_critical( > - Rate_monotonic_Control *the_period, > - ISR_lock_Context *lock_context > + Thread_Control *the_thread, > + ISR_lock_Context *lock_context > ) > { > - _ISR_lock_Acquire( &the_period->Lock, lock_context ); > + _Thread_Wait_acquire_default_critical( the_thread, lock_context ); > } At what version did you make your patch? These lock changes are weird. > > RTEMS_INLINE_ROUTINE void _Rate_monotonic_Release( > - Rate_monotonic_Control *the_period, > - ISR_lock_Context *lock_context > + Thread_Control *the_thread, > + ISR_lock_Context *lock_context > ) > { > - _ISR_lock_Release_and_ISR_enable( &the_period->Lock, lock_context ); > + _Thread_Wait_release_default( the_thread, lock_context ); > } > > RTEMS_INLINE_ROUTINE Rate_monotonic_Control *_Rate_monotonic_Get( > @@ -116,6 +117,18 @@ bool _Rate_monotonic_Get_status( > Timestamp_Control *cpu_since_last_period > ); > > +/** > + * @brief Renew the watchdog deadline > + * > + * This routine is prepared for the watchdog timeout to renew its deadline > + * without releasing jobs. > + */ > +void _Rate_monotonic_Renew_deadline( > + Rate_monotonic_Control *the_period, > + Thread_Control *owner, > + ISR_lock_Context *lock_context > +); > + > void _Rate_monotonic_Restart( > Rate_monotonic_Control *the_period, > Thread_Control *owner, > diff --git a/cpukit/rtems/src/ratemonperiod.c > b/cpukit/rtems/src/ratemonperiod.c > index 77bd996..26cee58 100644 > --- a/cpukit/rtems/src/ratemonperiod.c > +++ b/cpukit/rtems/src/ratemonperiod.c > @@ -9,6 +9,7 @@ > * COPYRIGHT (c) 1989-2010. > * On-Line Applications Research Corporation (OAR). > * Copyright (c) 2016 embedded brains GmbH. > + * COPYRIGHT (c) 2016 Kuan-Hsun Chen, TU Dortmund University (TUDo). > * > * The license and distribution terms for this file may be > * found in the file LICENSE in this distribution or at > @@ -63,6 +64,24 @@ bool _Rate_monotonic_Get_status( > return true; > } > > +static void _Rate_monotonic_Release_postponedjob( better; Release_postponed_job > + Rate_monotonic_Control *the_period, > + Thread_Control *owner, > + rtems_interval next_length, > + ISR_lock_Context *lock_context > +) > +{ > + /* This function only releases the postponed jobs. */ > + Per_CPU_Control *cpu_self; > + cpu_self = _Thread_Dispatch_disable_critical( lock_context ); > + _Rate_monotonic_Release( owner, lock_context ); > + > + the_period->postponed_jobs -=1; > + _Scheduler_Release_job( owner, the_period->latest_deadline ); > + > + _Thread_Dispatch_enable( cpu_self ); > +} > + > static void _Rate_monotonic_Release_job( > Rate_monotonic_Control *the_period, > Thread_Control *owner, > @@ -70,29 +89,49 @@ static void _Rate_monotonic_Release_job( > ISR_lock_Context *lock_context > ) > { > - Per_CPU_Control *cpu_self; > - Thread_queue_Context queue_context; > - uint64_t deadline; > + Per_CPU_Control *cpu_self; > + uint64_t deadline; > > cpu_self = _Thread_Dispatch_disable_critical( lock_context ); > + _Rate_monotonic_Release( owner, lock_context ); > > + _ISR_lock_ISR_disable( lock_context ); > deadline = _Watchdog_Per_CPU_insert_relative( > &the_period->Timer, > cpu_self, > next_length > ); > - _Scheduler_Release_job( > - owner, > - &the_period->Priority, > - deadline, > - &queue_context > - ); > + _ISR_lock_ISR_enable( lock_context ); > + > + _Scheduler_Release_job( owner, deadline ); > > - _Rate_monotonic_Release( the_period, lock_context ); > - _Thread_Priority_update( &queue_context ); > _Thread_Dispatch_enable( cpu_self ); > } > > +void _Rate_monotonic_Renew_deadline( > + Rate_monotonic_Control *the_period, > + Thread_Control *owner, > + ISR_lock_Context *lock_context > +) > +{ > + Per_CPU_Control *cpu_self; > + uint64_t deadline; > + > + cpu_self = _Thread_Dispatch_disable_critical( lock_context ); > + _Rate_monotonic_Release( owner, lock_context ); > + > + _ISR_lock_ISR_disable( lock_context ); > + deadline = _Watchdog_Per_CPU_insert_relative( > + &the_period->Timer, > + cpu_self, > + the_period->next_length > + ); > + the_period->latest_deadline = deadline; > + _ISR_lock_ISR_enable( lock_context ); > + _Thread_Dispatch_enable( cpu_self ); > + > +} > + > void _Rate_monotonic_Restart( > Rate_monotonic_Control *the_period, > Thread_Control *owner, > @@ -190,6 +229,10 @@ static rtems_status_code _Rate_monotonic_Activate( > ISR_lock_Context *lock_context > ) > { > + > + /* Initialize the number of postponed job variable */ don't need this comment or the extra blank newlines around this. Just init the variable. > + the_period->postponed_jobs = 0; > + > the_period->state = RATE_MONOTONIC_ACTIVE; > the_period->next_length = length; > _Rate_monotonic_Restart( the_period, executing, lock_context ); > @@ -221,7 +264,7 @@ static rtems_status_code > _Rate_monotonic_Block_while_active( > _Thread_Wait_flags_set( executing, RATE_MONOTONIC_INTEND_TO_BLOCK ); > > cpu_self = _Thread_Dispatch_disable_critical( lock_context ); > - _Rate_monotonic_Release( the_period, lock_context ); > + _Rate_monotonic_Release( executing, lock_context ); > > _Thread_Set_state( executing, STATES_WAITING_FOR_PERIOD ); > > @@ -241,6 +284,11 @@ static rtems_status_code > _Rate_monotonic_Block_while_active( > return RTEMS_SUCCESSFUL; > } > > +/* > + * There are two possible cases: one is that the previous deadline is missed, > + * The other is that the number of postponed jobs is not 0, but the current > + * deadline is still not expired, i.e., state = RATE_MONOTONIC_ACTIVE. > + */ > static rtems_status_code _Rate_monotonic_Block_while_expired( > Rate_monotonic_Control *the_period, > rtems_interval length, > @@ -248,6 +296,12 @@ static rtems_status_code > _Rate_monotonic_Block_while_expired( > ISR_lock_Context *lock_context > ) > { > + /* > + * No matter the just finished jobs in time or not, > + * they are actually missing their deadlines already. > + */ > + the_period->state = RATE_MONOTONIC_EXPIRED; > + > /* > * Update statistics from the concluding period > */ > @@ -255,11 +309,27 @@ static rtems_status_code > _Rate_monotonic_Block_while_expired( > > the_period->state = RATE_MONOTONIC_ACTIVE; > the_period->next_length = length; > - > - _Rate_monotonic_Release_job( the_period, executing, length, lock_context ); > + > + _Rate_monotonic_Release_postponedjob( the_period, executing, length, > lock_context ); > return RTEMS_TIMEOUT; > } > > +uint32_t rtems_rate_monotonic_Postponed_num( Is this function used/needed to be used? > + rtems_id period_id > +) > +{ > + Rate_monotonic_Control *the_period; > + ISR_lock_Context lock_context; > + Thread_Control *owner; > + > + the_period = _Rate_monotonic_Get( period_id, &lock_context ); > + _Assert(the_period != NULL); > + uint32_t jobs = the_period->postponed_jobs; > + owner = the_period->owner; > + _Rate_monotonic_Release( owner, &lock_context ); > + return jobs; > +} > + > rtems_status_code rtems_rate_monotonic_period( > rtems_id id, > rtems_interval length > @@ -282,22 +352,44 @@ rtems_status_code rtems_rate_monotonic_period( > return RTEMS_NOT_OWNER_OF_RESOURCE; > } > > - _Rate_monotonic_Acquire_critical( the_period, &lock_context ); > + _Rate_monotonic_Acquire_critical( executing, &lock_context ); > > state = the_period->state; > > if ( length == RTEMS_PERIOD_STATUS ) { > status = _Rate_monotonic_Get_status_for_state( state ); > - _Rate_monotonic_Release( the_period, &lock_context ); > + _Rate_monotonic_Release( executing, &lock_context ); > } else { > switch ( state ) { > case RATE_MONOTONIC_ACTIVE: > - status = _Rate_monotonic_Block_while_active( > - the_period, > - length, > - executing, > - &lock_context > - ); > + > + if(the_period->postponed_jobs > 0){ fix whitespace > + /* > + * If the number of postponed jobs is not 0, it means the > + * previous postponed instance is finished without exceeding > + * the current period deadline. > + * align asterisks. > + * Do nothing on the watchdog deadline assignment but release the > next > + * remaining postponed job. > + */ > + status = _Rate_monotonic_Block_while_expired( > + the_period, > + length, > + executing, > + &lock_context > + ); > + }else{ fix ws > + /* > + * Normal case that no postponed jobs and no expiration, so wait > for the period > + * and update the deadline of watchdog accordingly. > + */ > + status = _Rate_monotonic_Block_while_active( > + the_period, > + length, > + executing, > + &lock_context > + ); > + } > break; > case RATE_MONOTONIC_INACTIVE: > status = _Rate_monotonic_Activate( > @@ -308,6 +400,14 @@ rtems_status_code rtems_rate_monotonic_period( > ); > break; > default: > + /* > + * As now this period was already TIMEOUT, there must be at least one > + * postponed job recorded by the watchdog. The one which exceeded > + * the previous deadline"s" was just finished. remove those double-quotes. > + * > + * Maybe there is more than one job postponed due to the preemption > or > + * the previous finished job. > + */ > _Assert( state == RATE_MONOTONIC_EXPIRED ); > status = _Rate_monotonic_Block_while_expired( > the_period, > diff --git a/cpukit/rtems/src/ratemontimeout.c > b/cpukit/rtems/src/ratemontimeout.c > index e514a31..be0a770 100644 > --- a/cpukit/rtems/src/ratemontimeout.c > +++ b/cpukit/rtems/src/ratemontimeout.c > @@ -9,6 +9,8 @@ > * COPYRIGHT (c) 1989-2009. > * On-Line Applications Research Corporation (OAR). > * > + * COPYRIGHT (c) 2016 Kuan-Hsun Chen, TU Dortmund University (TUDo). > + * > * The license and distribution terms for this file may be > * found in the file LICENSE in this distribution or at > * http://www.rtems.org/license/LICENSE. > @@ -31,7 +33,7 @@ void _Rate_monotonic_Timeout( Watchdog_Control > *the_watchdog ) > owner = the_period->owner; > > _ISR_lock_ISR_disable( &lock_context ); > - _Rate_monotonic_Acquire_critical( the_period, &lock_context ); > + _Rate_monotonic_Acquire_critical( owner, &lock_context ); > wait_flags = _Thread_Wait_flags_get( owner ); > > if ( > @@ -62,7 +64,14 @@ void _Rate_monotonic_Timeout( Watchdog_Control > *the_watchdog ) > _Thread_Unblock( owner ); > } > } else { > + /* > + * If the watchdog is timeout, it means there is an additional postponed > + * job in the next period but it is not available to release now: > + * Either the current task is still executed, or it is preemptive by the > + * other higher priority tasks. > + */ > + the_period->postponed_jobs += 1; > the_period->state = RATE_MONOTONIC_EXPIRED; > - _Rate_monotonic_Release( the_period, &lock_context ); > + _Rate_monotonic_Renew_deadline( the_period, owner, &lock_context ); > } > } > -- > 1.9.1 > > _______________________________________________ > devel mailing list > devel@rtems.org > http://lists.rtems.org/mailman/listinfo/devel _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel