[PATCH 3/4] score: Add _Thread_Get_interrupt_disable()

Sebastian Huber sebastian.huber at embedded-brains.de
Mon Apr 20 13:45:05 UTC 2015


Remove _Thread_Acquire() and _Thread_Acquire_for_executing().  Add
utility functions for the default thread lock.   Use the default thread
lock for the RTEMS events.  There is no need to disable thread
dispatching and a Giant acquire in _Event_Timeout() since this was
already done by the caller.

Update #2273.
---
 cpukit/rtems/src/eventreceive.c               | 12 ++--
 cpukit/rtems/src/eventseize.c                 | 17 ++---
 cpukit/rtems/src/eventsend.c                  |  3 +-
 cpukit/rtems/src/eventsurrender.c             | 10 +--
 cpukit/rtems/src/eventtimeout.c               | 74 ++++++++--------------
 cpukit/rtems/src/systemeventreceive.c         | 12 ++--
 cpukit/rtems/src/systemeventsend.c            |  3 +-
 cpukit/score/include/rtems/score/threadimpl.h | 89 ++++++++++++++++++++++++---
 cpukit/score/src/threadget.c                  | 22 ++-----
 testsuites/sptests/spintrcritical10/init.c    | 12 ++--
 10 files changed, 146 insertions(+), 108 deletions(-)

diff --git a/cpukit/rtems/src/eventreceive.c b/cpukit/rtems/src/eventreceive.c
index 07e1c57..14f93db 100644
--- a/cpukit/rtems/src/eventreceive.c
+++ b/cpukit/rtems/src/eventreceive.c
@@ -34,9 +34,13 @@ rtems_status_code rtems_event_receive(
 
   if ( event_out != NULL ) {
     ISR_lock_Context   lock_context;
-    Thread_Control    *executing = _Thread_Acquire_executing( &lock_context );
-    RTEMS_API_Control *api = executing->API_Extensions[ THREAD_API_RTEMS ];
-    Event_Control     *event = &api->Event;
+    Thread_Control    *executing;
+    RTEMS_API_Control *api;
+    Event_Control     *event;
+
+    executing = _Thread_Lock_acquire_default_for_executing( &lock_context );
+    api = executing->API_Extensions[ THREAD_API_RTEMS ];
+    event = &api->Event;
 
     if ( !_Event_sets_Is_empty( event_in ) ) {
       _Event_Seize(
@@ -54,7 +58,7 @@ rtems_status_code rtems_event_receive(
       sc = executing->Wait.return_code;
     } else {
       *event_out = event->pending_events;
-      _Objects_Release_and_ISR_enable( &executing->Object, &lock_context );
+      _Thread_Lock_release_default( executing, &lock_context );
       sc = RTEMS_SUCCESSFUL;
     }
   } else {
diff --git a/cpukit/rtems/src/eventseize.c b/cpukit/rtems/src/eventseize.c
index 59a2b62..9296656 100644
--- a/cpukit/rtems/src/eventseize.c
+++ b/cpukit/rtems/src/eventseize.c
@@ -57,13 +57,13 @@ void _Event_Seize(
        (seized_events == event_in || _Options_Is_any( option_set )) ) {
     event->pending_events =
       _Event_sets_Clear( pending_events, seized_events );
-    _Objects_Release_and_ISR_enable( &executing->Object, lock_context );
+    _Thread_Lock_release_default( executing, lock_context );
     *event_out = seized_events;
     return;
   }
 
   if ( _Options_Is_no_wait( option_set ) ) {
-    _Objects_Release_and_ISR_enable( &executing->Object, lock_context );
+    _Thread_Lock_release_default( executing, lock_context );
     executing->Wait.return_code = RTEMS_UNSATISFIED;
     *event_out = seized_events;
     return;
@@ -84,19 +84,12 @@ void _Event_Seize(
   executing->Wait.return_argument = event_out;
   _Thread_Wait_flags_set( executing, intend_to_block );
 
-  cpu_self = _Objects_Release_and_thread_dispatch_disable(
-    &executing->Object,
-    lock_context
-  );
+  cpu_self = _Thread_Dispatch_disable_critical();
+  _Thread_Lock_release_default( executing, lock_context );
   _Giant_Acquire( cpu_self );
 
   if ( ticks ) {
-    _Watchdog_Initialize(
-      &executing->Timer,
-      _Event_Timeout,
-      executing->Object.id,
-      NULL
-    );
+    _Watchdog_Initialize( &executing->Timer, _Event_Timeout, 0, executing );
     _Watchdog_Insert_ticks( &executing->Timer, ticks );
   }
 
diff --git a/cpukit/rtems/src/eventsend.c b/cpukit/rtems/src/eventsend.c
index bb9ca33..c9e81fb 100644
--- a/cpukit/rtems/src/eventsend.c
+++ b/cpukit/rtems/src/eventsend.c
@@ -33,7 +33,7 @@ rtems_status_code rtems_event_send(
   RTEMS_API_Control *api;
   ISR_lock_Context   lock_context;
 
-  thread = _Thread_Acquire( id, &location, &lock_context );
+  thread = _Thread_Get_interrupt_disable( id, &location, &lock_context );
   switch ( location ) {
     case OBJECTS_LOCAL:
       api = thread->API_Extensions[ THREAD_API_RTEMS ];
@@ -44,6 +44,7 @@ rtems_status_code rtems_event_send(
         THREAD_WAIT_CLASS_EVENT,
         &lock_context
       );
+      _Objects_Put_for_get_isr_disable( &thread->Object );
       sc = RTEMS_SUCCESSFUL;
       break;
 #ifdef RTEMS_MULTIPROCESSING
diff --git a/cpukit/rtems/src/eventsurrender.c b/cpukit/rtems/src/eventsurrender.c
index 824912b..ba4e429 100644
--- a/cpukit/rtems/src/eventsurrender.c
+++ b/cpukit/rtems/src/eventsurrender.c
@@ -64,6 +64,8 @@ void _Event_Surrender(
   Thread_Wait_flags wait_flags;
   bool              unblock;
 
+  _Thread_Lock_acquire_default_critical( the_thread, lock_context );
+
   _Event_sets_Post( event_in, &event->pending_events );
   pending_events = event->pending_events;
 
@@ -105,10 +107,8 @@ void _Event_Surrender(
   if ( unblock ) {
     Per_CPU_Control *cpu_self;
 
-    cpu_self = _Objects_Release_and_thread_dispatch_disable(
-      &the_thread->Object,
-      lock_context
-    );
+    cpu_self = _Thread_Dispatch_disable_critical();
+    _Thread_Lock_release_default( the_thread, lock_context );
     _Giant_Acquire( cpu_self );
 
     _Watchdog_Remove( &the_thread->Timer );
@@ -117,6 +117,6 @@ void _Event_Surrender(
     _Giant_Release( cpu_self );
     _Thread_Dispatch_enable( cpu_self );
   } else {
-    _Objects_Release_and_ISR_enable( &the_thread->Object, lock_context );
+    _Thread_Lock_release_default( the_thread, lock_context );
   }
 }
diff --git a/cpukit/rtems/src/eventtimeout.c b/cpukit/rtems/src/eventtimeout.c
index 295f0c5..9c09174 100644
--- a/cpukit/rtems/src/eventtimeout.c
+++ b/cpukit/rtems/src/eventtimeout.c
@@ -27,7 +27,6 @@ void _Event_Timeout(
 )
 {
   Thread_Control    *the_thread;
-  Objects_Locations  location;
   ISR_lock_Context   lock_context;
   Thread_Wait_flags  wait_flags;
   Thread_Wait_flags  wait_class;
@@ -36,55 +35,36 @@ void _Event_Timeout(
   bool               success;
   bool               unblock;
 
-  the_thread = _Thread_Acquire( id, &location, &lock_context );
-  switch ( location ) {
-    case OBJECTS_LOCAL:
-      wait_flags = _Thread_Wait_flags_get( the_thread );
-      wait_class = wait_flags & THREAD_WAIT_CLASS_MASK;
-      intend_to_block = wait_class | THREAD_WAIT_STATE_INTEND_TO_BLOCK;
-      blocked = wait_class | THREAD_WAIT_STATE_BLOCKED;
-      success = _Thread_Wait_flags_try_change_critical(
-        the_thread,
-        intend_to_block,
-        wait_class | THREAD_WAIT_STATE_INTERRUPT_TIMEOUT
-      );
+  the_thread = arg;
+  _Thread_Lock_acquire_default( the_thread, &lock_context );
 
-      if ( success ) {
-        the_thread->Wait.return_code = RTEMS_TIMEOUT;
-        unblock = false;
-      } else if ( _Thread_Wait_flags_get( the_thread ) == blocked ) {
-        the_thread->Wait.return_code = RTEMS_TIMEOUT;
-        _Thread_Wait_flags_set(
-          the_thread,
-          wait_class | THREAD_WAIT_STATE_TIMEOUT
-        );
-        unblock = true;
-      } else {
-        unblock = false;
-      }
+  wait_flags = _Thread_Wait_flags_get( the_thread );
+  wait_class = wait_flags & THREAD_WAIT_CLASS_MASK;
+  intend_to_block = wait_class | THREAD_WAIT_STATE_INTEND_TO_BLOCK;
+  blocked = wait_class | THREAD_WAIT_STATE_BLOCKED;
+  success = _Thread_Wait_flags_try_change_critical(
+    the_thread,
+    intend_to_block,
+    wait_class | THREAD_WAIT_STATE_INTERRUPT_TIMEOUT
+  );
 
-      if ( unblock ) {
-        Per_CPU_Control *cpu_self;
-
-        cpu_self = _Objects_Release_and_thread_dispatch_disable(
-          &the_thread->Object,
-          &lock_context
-        );
-        _Giant_Acquire( cpu_self );
-
-        _Thread_Unblock( the_thread );
+  if ( success ) {
+    the_thread->Wait.return_code = RTEMS_TIMEOUT;
+    unblock = false;
+  } else if ( _Thread_Wait_flags_get( the_thread ) == blocked ) {
+    the_thread->Wait.return_code = RTEMS_TIMEOUT;
+    _Thread_Wait_flags_set(
+      the_thread,
+      wait_class | THREAD_WAIT_STATE_TIMEOUT
+    );
+    unblock = true;
+  } else {
+    unblock = false;
+  }
 
-        _Giant_Release( cpu_self );
-        _Thread_Dispatch_enable( cpu_self );
-      } else {
-        _Objects_Release_and_ISR_enable( &the_thread->Object, &lock_context );
-      }
+  _Thread_Lock_release_default( the_thread, &lock_context );
 
-      break;
-#if defined(RTEMS_MULTIPROCESSING)
-    case OBJECTS_REMOTE:  /* impossible */
-#endif
-    case OBJECTS_ERROR:
-      break;
+  if ( unblock ) {
+    _Thread_Unblock( the_thread );
   }
 }
diff --git a/cpukit/rtems/src/systemeventreceive.c b/cpukit/rtems/src/systemeventreceive.c
index 394b26e..c33f468 100644
--- a/cpukit/rtems/src/systemeventreceive.c
+++ b/cpukit/rtems/src/systemeventreceive.c
@@ -40,9 +40,13 @@ rtems_status_code rtems_event_system_receive(
 
   if ( event_out != NULL ) {
     ISR_lock_Context   lock_context;
-    Thread_Control    *executing = _Thread_Acquire_executing( &lock_context );
-    RTEMS_API_Control *api = executing->API_Extensions[ THREAD_API_RTEMS ];
-    Event_Control     *event = &api->System_event;
+    Thread_Control    *executing;
+    RTEMS_API_Control *api;
+    Event_Control     *event;
+
+    executing = _Thread_Lock_acquire_default_for_executing( &lock_context );
+    api = executing->API_Extensions[ THREAD_API_RTEMS ];
+    event = &api->System_event;
 
     if ( !_Event_sets_Is_empty( event_in ) ) {
       _Event_Seize(
@@ -60,7 +64,7 @@ rtems_status_code rtems_event_system_receive(
       sc = executing->Wait.return_code;
     } else {
       *event_out = event->pending_events;
-      _Objects_Release_and_ISR_enable( &executing->Object, &lock_context );
+      _Thread_Lock_release_default( executing, &lock_context );
       sc = RTEMS_SUCCESSFUL;
     }
   } else {
diff --git a/cpukit/rtems/src/systemeventsend.c b/cpukit/rtems/src/systemeventsend.c
index d35127d..1892c13 100644
--- a/cpukit/rtems/src/systemeventsend.c
+++ b/cpukit/rtems/src/systemeventsend.c
@@ -39,7 +39,7 @@ rtems_status_code rtems_event_system_send(
   RTEMS_API_Control *api;
   ISR_lock_Context   lock_context;
 
-  thread = _Thread_Acquire( id, &location, &lock_context );
+  thread = _Thread_Get_interrupt_disable( id, &location, &lock_context );
   switch ( location ) {
     case OBJECTS_LOCAL:
       api = thread->API_Extensions[ THREAD_API_RTEMS ];
@@ -50,6 +50,7 @@ rtems_status_code rtems_event_system_send(
         THREAD_WAIT_CLASS_SYSTEM_EVENT,
         &lock_context
       );
+      _Objects_Put_for_get_isr_disable( &thread->Object );
       sc = RTEMS_SUCCESSFUL;
       break;
 #ifdef RTEMS_MULTIPROCESSING
diff --git a/cpukit/score/include/rtems/score/threadimpl.h b/cpukit/score/include/rtems/score/threadimpl.h
index 1ccc4d6..9a621a8 100644
--- a/cpukit/score/include/rtems/score/threadimpl.h
+++ b/cpukit/score/include/rtems/score/threadimpl.h
@@ -22,6 +22,7 @@
 #define _RTEMS_SCORE_THREADIMPL_H
 
 #include <rtems/score/thread.h>
+#include <rtems/score/assert.h>
 #include <rtems/score/chainimpl.h>
 #include <rtems/score/interr.h>
 #include <rtems/score/isr.h>
@@ -382,23 +383,16 @@ Thread_Control *_Thread_Get (
 );
 
 /**
- * @brief Acquires a thread by its identifier.
+ * @brief Gets a thread by its identifier.
  *
- * @see _Objects_Acquire().
+ * @see _Objects_Get_isr_disable().
  */
-Thread_Control *_Thread_Acquire(
+Thread_Control *_Thread_Get_interrupt_disable(
   Objects_Id         id,
   Objects_Locations *location,
   ISR_lock_Context  *lock_context
 );
 
-/**
- * @brief Acquires the executing thread.
- *
- * @see _Objects_Acquire().
- */
-Thread_Control *_Thread_Acquire_executing( ISR_lock_Context *lock_context );
-
 RTEMS_INLINE_ROUTINE Per_CPU_Control *_Thread_Get_CPU(
   const Thread_Control *thread
 )
@@ -866,6 +860,81 @@ RTEMS_INLINE_ROUTINE bool _Thread_Owns_resources(
 }
 
 /**
+ * @brief Acquires the default thread lock and returns the executing thread.
+ *
+ * @param[in] lock_context The lock context used for the corresponding lock
+ * release.
+ *
+ * @return The executing thread.
+ *
+ * @see _Thread_Lock_release_default().
+ */
+RTEMS_INLINE_ROUTINE Thread_Control *_Thread_Lock_acquire_default_for_executing(
+  ISR_lock_Context *lock_context
+)
+{
+  Thread_Control *executing;
+
+  _ISR_lock_ISR_disable( lock_context );
+  executing = _Thread_Executing;
+  _ISR_lock_Acquire( &executing->Lock.Default, lock_context );
+
+  return executing;
+}
+
+/**
+ * @brief Acquires the default thread lock inside a critical section
+ * (interrupts disabled).
+ *
+ * @param[in] the_thread The thread.
+ * @param[in] lock_context The lock context used for the corresponding lock
+ * release.
+ *
+ * @see _Thread_Lock_release_default().
+ */
+RTEMS_INLINE_ROUTINE void _Thread_Lock_acquire_default_critical(
+  Thread_Control   *the_thread,
+  ISR_lock_Context *lock_context
+)
+{
+  _Assert( _ISR_Get_level() != 0 );
+  _ISR_lock_Acquire( &the_thread->Lock.Default, lock_context );
+}
+
+/**
+ * @brief Acquires the default thread lock.
+ *
+ * @param[in] the_thread The thread.
+ * @param[in] lock_context The lock context used for the corresponding lock
+ * release.
+ *
+ * @see _Thread_Lock_release_default().
+ */
+RTEMS_INLINE_ROUTINE void _Thread_Lock_acquire_default(
+  Thread_Control   *the_thread,
+  ISR_lock_Context *lock_context
+)
+{
+  _Assert( _ISR_Get_level() != 0 );
+  _ISR_lock_ISR_disable_and_acquire( &the_thread->Lock.Default, lock_context );
+}
+
+/**
+ * @brief Release the default thread lock.
+ *
+ * @param[in] the_thread The thread.
+ * @param[in] lock_context The lock context used for the corresponding lock
+ * acquire.
+ */
+RTEMS_INLINE_ROUTINE void _Thread_Lock_release_default(
+  Thread_Control   *the_thread,
+  ISR_lock_Context *lock_context
+)
+{
+  _ISR_lock_Release_and_ISR_enable( &the_thread->Lock.Default, lock_context );
+}
+
+/**
  * @brief Release the thread lock.
  *
  * @param[in] lock The lock returned by _Thread_Lock_acquire().
diff --git a/cpukit/score/src/threadget.c b/cpukit/score/src/threadget.c
index 1091333..45ea55f 100644
--- a/cpukit/score/src/threadget.c
+++ b/cpukit/score/src/threadget.c
@@ -75,22 +75,7 @@ Thread_Control *_Thread_Get(
   return (Thread_Control *) _Objects_Get( information, id, location );
 }
 
-Thread_Control *_Thread_Acquire_executing( ISR_lock_Context *lock_context )
-{
-  Thread_Control *executing;
-
-#if defined(RTEMS_SMP)
-  _ISR_Disable_without_giant( lock_context->Lock_context.isr_level );
-#else
-  _ISR_Disable( lock_context->isr_level );
-#endif
-  executing = _Thread_Executing;
-  _ISR_lock_Acquire( &executing->Object.Lock, lock_context );
-
-  return executing;
-}
-
-Thread_Control *_Thread_Acquire(
+Thread_Control *_Thread_Get_interrupt_disable(
   Objects_Id         id,
   Objects_Locations *location,
   ISR_lock_Context  *lock_context
@@ -100,7 +85,8 @@ Thread_Control *_Thread_Acquire(
 
   if ( _Objects_Are_ids_equal( id, OBJECTS_ID_OF_SELF ) ) {
     *location = OBJECTS_LOCAL;
-    return _Thread_Acquire_executing( lock_context );
+    _ISR_lock_ISR_disable( lock_context );
+    return _Thread_Executing;
   }
 
   information = _Thread_Get_objects_information( id );
@@ -110,5 +96,5 @@ Thread_Control *_Thread_Acquire(
   }
 
   return (Thread_Control *)
-    _Objects_Acquire( information, id, location, lock_context );
+    _Objects_Get_isr_disable( information, id, location, lock_context );
 }
diff --git a/testsuites/sptests/spintrcritical10/init.c b/testsuites/sptests/spintrcritical10/init.c
index 4d25ce6..441b161 100644
--- a/testsuites/sptests/spintrcritical10/init.c
+++ b/testsuites/sptests/spintrcritical10/init.c
@@ -51,7 +51,7 @@ static void any_satisfy_before_timeout(rtems_id timer, void *arg)
 {
   rtems_status_code sc;
   test_context *ctx = arg;
-  const Thread_Control *thread = ctx->thread;
+  Thread_Control *thread = ctx->thread;
   Thread_Wait_flags flags = _Thread_Wait_flags_get(thread);
 
   if (blocks_for_event(flags)) {
@@ -78,7 +78,7 @@ static void any_satisfy_before_timeout(rtems_id timer, void *arg)
     );
     rtems_test_assert(thread->Wait.return_code == RTEMS_SUCCESSFUL);
 
-    _Event_Timeout(thread->Object.id, NULL);
+    _Event_Timeout(0, thread);
 
     rtems_test_assert(
       *(rtems_event_set *) thread->Wait.return_argument == GREEN
@@ -148,7 +148,7 @@ static void all_satisfy_before_timeout(rtems_id timer, void *arg)
 {
   rtems_status_code sc;
   test_context *ctx = arg;
-  const Thread_Control *thread = ctx->thread;
+  Thread_Control *thread = ctx->thread;
   Thread_Wait_flags flags = _Thread_Wait_flags_get(thread);
 
   if (blocks_for_event(flags)) {
@@ -175,7 +175,7 @@ static void all_satisfy_before_timeout(rtems_id timer, void *arg)
     );
     rtems_test_assert(thread->Wait.return_code == RTEMS_SUCCESSFUL);
 
-    _Event_Timeout(thread->Object.id, NULL);
+    _Event_Timeout(0, thread);
 
     rtems_test_assert(
       *(rtems_event_set *) thread->Wait.return_argument == EVENTS
@@ -240,7 +240,7 @@ static void timeout_before_satisfied(rtems_id timer, void *arg)
 {
   rtems_status_code sc;
   test_context *ctx = arg;
-  const Thread_Control *thread = ctx->thread;
+  Thread_Control *thread = ctx->thread;
   Thread_Wait_flags flags = _Thread_Wait_flags_get(thread);
 
   if (blocks_for_event(flags)) {
@@ -251,7 +251,7 @@ static void timeout_before_satisfied(rtems_id timer, void *arg)
     );
     rtems_test_assert(thread->Wait.return_code == RTEMS_SUCCESSFUL);
 
-    _Event_Timeout(thread->Object.id, NULL);
+    _Event_Timeout(0, thread);
 
     rtems_test_assert(
       *(rtems_event_set *) thread->Wait.return_argument == DEADBEEF
-- 
1.8.4.5




More information about the devel mailing list