[PATCH] Enhancement of the RMS manager for the overrun handling.
Gedare Bloom
gedare at rtems.org
Tue Dec 20 22:10:18 UTC 2016
On Fri, Dec 9, 2016 at 11:21 AM, Kuan-Hsun Chen <c0066c at 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 at rtems.org
> http://lists.rtems.org/mailman/listinfo/devel
More information about the devel
mailing list