summaryrefslogtreecommitdiffstats
path: root/cpukit/rtems/src/ratemontimeout.c
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2016-03-21 15:01:57 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2016-03-22 07:05:05 +0100
commit90960bd11a91259d9aace3870692dbe2e227de0f (patch)
tree3d88f8bc3d1fe17252e8290cadae2afb4a38ce4b /cpukit/rtems/src/ratemontimeout.c
parentrtems: Avoid __RTEMS_USE_TICKS_FOR_STATISTICS__ (diff)
downloadrtems-90960bd11a91259d9aace3870692dbe2e227de0f.tar.bz2
rtems: Rework rate-monotonic scheduler
Use the default thread lock to protect rate-monotonic state changes. This avoids use of the Giant lock. Split rtems_rate_monotonic_period() body into several static functions. Introduce a new thread wait class THREAD_WAIT_CLASS_PERIOD for period objects to synchronize the blocking operation. Close #2631.
Diffstat (limited to 'cpukit/rtems/src/ratemontimeout.c')
-rw-r--r--cpukit/rtems/src/ratemontimeout.c63
1 files changed, 40 insertions, 23 deletions
diff --git a/cpukit/rtems/src/ratemontimeout.c b/cpukit/rtems/src/ratemontimeout.c
index 7c25595a16..78c78e2a7f 100644
--- a/cpukit/rtems/src/ratemontimeout.c
+++ b/cpukit/rtems/src/ratemontimeout.c
@@ -19,33 +19,50 @@
#endif
#include <rtems/rtems/ratemonimpl.h>
-#include <rtems/score/threadimpl.h>
-#include <rtems/score/watchdogimpl.h>
-void _Rate_monotonic_Timeout( Watchdog_Control *watchdog )
+void _Rate_monotonic_Timeout( Watchdog_Control *the_watchdog )
{
Rate_monotonic_Control *the_period;
- Thread_Control *the_thread;
-
- /*
- * When we get here, the Timer is already off the chain so we do not
- * have to worry about that -- hence no _Watchdog_Remove().
- */
- the_period = RTEMS_CONTAINER_OF( watchdog, Rate_monotonic_Control, Timer );
- the_thread = the_period->owner;
-
- _Thread_Disable_dispatch();
-
- if ( _States_Is_waiting_for_period( the_thread->current_state ) &&
- the_thread->Wait.id == the_period->Object.id ) {
- _Thread_Unblock( the_thread );
- _Rate_monotonic_Restart( the_period );
- } else if ( the_period->state == RATE_MONOTONIC_OWNER_IS_BLOCKING ) {
- the_period->state = RATE_MONOTONIC_EXPIRED_WHILE_BLOCKING;
- _Rate_monotonic_Restart( the_period );
+ Thread_Control *owner;
+ ISR_lock_Context lock_context;
+ Thread_Wait_flags wait_flags;
+
+ the_period = RTEMS_CONTAINER_OF( the_watchdog, Rate_monotonic_Control, Timer );
+ owner = the_period->owner;
+
+ _ISR_lock_ISR_disable( &lock_context );
+ _Rate_monotonic_Acquire_critical( owner, &lock_context );
+ wait_flags = _Thread_Wait_flags_get( owner );
+
+ if (
+ ( wait_flags & THREAD_WAIT_CLASS_PERIOD ) != 0
+ && owner->Wait.return_argument == the_period
+ ) {
+ bool unblock;
+ bool success;
+
+ owner->Wait.return_argument = NULL;
+
+ success = _Thread_Wait_flags_try_change_critical(
+ owner,
+ RATE_MONOTONIC_INTEND_TO_BLOCK,
+ RATE_MONOTONIC_READY_AGAIN
+ );
+ if ( success ) {
+ unblock = false;
+ } else {
+ _Assert( _Thread_Wait_flags_get( owner ) == RATE_MONOTONIC_BLOCKED );
+ _Thread_Wait_flags_set( owner, RATE_MONOTONIC_READY_AGAIN );
+ unblock = true;
+ }
+
+ _Rate_monotonic_Restart( the_period, owner, &lock_context );
+
+ if ( unblock ) {
+ _Thread_Unblock( owner );
+ }
} else {
the_period->state = RATE_MONOTONIC_EXPIRED;
+ _Rate_monotonic_Release( owner, &lock_context );
}
-
- _Thread_Unnest_dispatch();
}