[PATCH] score: Relax thread begin extension environment

Sebastian Huber sebastian.huber at embedded-brains.de
Fri Jul 22 10:38:03 UTC 2016


Update #2752.
---
 cpukit/score/src/threadhandler.c         | 15 ++++---
 testsuites/sptests/spextensions01/init.c | 74 ++++++++++++++++++++++++++++++++
 2 files changed, 82 insertions(+), 7 deletions(-)

diff --git a/cpukit/score/src/threadhandler.c b/cpukit/score/src/threadhandler.c
index 2fa6d07..9f004b9 100644
--- a/cpukit/score/src/threadhandler.c
+++ b/cpukit/score/src/threadhandler.c
@@ -59,13 +59,6 @@ void _Thread_Handler( void )
   _Thread_Restore_fp( executing );
 
   /*
-   * Take care that 'begin' extensions get to complete before
-   * 'switch' extensions can run.  This means must keep dispatch
-   * disabled until all 'begin' extensions complete.
-   */
-  _User_extensions_Thread_begin( executing );
-
-  /*
    * Do not use the level of the thread control block, since it has a
    * different format.
    */
@@ -86,6 +79,14 @@ void _Thread_Handler( void )
   _Thread_Do_dispatch( cpu_self, level );
 
   /*
+   * Invoke the thread begin extensions in the context of the thread entry
+   * function with thread dispatching enabled.  This enables use of dynamic
+   * memory allocation, creation of POSIX keys and use of C++ thread local
+   * storage.  Blocking synchronization primitives are allowed also.
+   */
+  _User_extensions_Thread_begin( executing );
+
+  /*
    *  RTEMS supports multiple APIs and each API can define a different
    *  thread/task prototype. The following code supports invoking the
    *  user thread entry point using the prototype expected.
diff --git a/testsuites/sptests/spextensions01/init.c b/testsuites/sptests/spextensions01/init.c
index 091d66f..7eac443 100644
--- a/testsuites/sptests/spextensions01/init.c
+++ b/testsuites/sptests/spextensions01/init.c
@@ -25,6 +25,10 @@
 
 #include <bsp.h>
 
+#include <rtems/score/apimutex.h>
+#include <rtems/score/sysstate.h>
+#include <rtems/score/threaddispatch.h>
+
 const char rtems_test_name[] = "SPEXTENSIONS 1";
 
 static int counter;
@@ -33,6 +37,48 @@ static int active_extensions = 2;
 
 static rtems_id master_task;
 
+static bool before_multitasking(void)
+{
+  return _System_state_Is_before_multitasking(_System_state_Get());
+}
+
+static bool life_protected(void)
+{
+  Thread_Control *executing;
+
+  executing = _Thread_Get_executing();
+
+  return (executing->Life.state & THREAD_LIFE_PROTECTED) != 0;
+}
+
+static void assert_normal_thread_context(void)
+{
+  assert(_Thread_Dispatch_is_enabled());
+  assert(!_RTEMS_Allocator_is_owner());
+  assert(!life_protected());
+}
+
+static void assert_life_protected_thread_context(void)
+{
+  assert(_Thread_Dispatch_is_enabled() || before_multitasking());
+  assert(!_RTEMS_Allocator_is_owner());
+  assert(life_protected() || before_multitasking());
+}
+
+static void assert_allocator_protected_thread_context(void)
+{
+  assert(_Thread_Dispatch_is_enabled() || before_multitasking());
+  assert(_RTEMS_Allocator_is_owner());
+  assert(life_protected() || before_multitasking());
+}
+
+static void assert_thread_dispatch_disabled_context(void)
+{
+  assert(!_Thread_Dispatch_is_enabled());
+  assert(!_RTEMS_Allocator_is_owner());
+  assert(!life_protected());
+}
+
 static void assert_static_order(int index)
 {
   assert((counter % active_extensions) == index);
@@ -54,22 +100,26 @@ static void assert_reverse_order(int index)
 static bool zero_thread_create(rtems_tcb *a, rtems_tcb *b)
 {
   assert_static_order(0);
+  assert_allocator_protected_thread_context();
   return true;
 }
 
 static void zero_thread_start(rtems_tcb *a, rtems_tcb *b)
 {
   assert_static_order(0);
+  assert_thread_dispatch_disabled_context();
 }
 
 static void zero_thread_restart(rtems_tcb *a, rtems_tcb *b)
 {
   assert_static_order(0);
+  assert_life_protected_thread_context();
 }
 
 static void zero_thread_delete(rtems_tcb *a, rtems_tcb *b)
 {
   assert_static_order(0);
+  assert_allocator_protected_thread_context();
 }
 
 static void zero_thread_switch(rtems_tcb *a, rtems_tcb *b)
@@ -80,11 +130,13 @@ static void zero_thread_switch(rtems_tcb *a, rtems_tcb *b)
 static void zero_thread_begin(rtems_tcb *a)
 {
   assert_static_order(0);
+  assert_normal_thread_context();
 }
 
 static void zero_thread_exitted(rtems_tcb *a)
 {
   assert_static_order(0);
+  assert_normal_thread_context();
 }
 
 static void zero_fatal(
@@ -101,27 +153,32 @@ static void zero_fatal(
 static void zero_thread_terminate(rtems_tcb *a)
 {
   assert_static_order(0);
+  assert_life_protected_thread_context();
 }
 
 static bool one_thread_create(rtems_tcb *a, rtems_tcb *b)
 {
   assert_static_order(1);
+  assert_allocator_protected_thread_context();
   return true;
 }
 
 static void one_thread_start(rtems_tcb *a, rtems_tcb *b)
 {
   assert_static_order(1);
+  assert_thread_dispatch_disabled_context();
 }
 
 static void one_thread_restart(rtems_tcb *a, rtems_tcb *b)
 {
   assert_static_order(1);
+  assert_life_protected_thread_context();
 }
 
 static void one_thread_delete(rtems_tcb *a, rtems_tcb *b)
 {
   assert_static_order(1);
+  assert_allocator_protected_thread_context();
 }
 
 static void one_thread_switch(rtems_tcb *a, rtems_tcb *b)
@@ -132,11 +189,13 @@ static void one_thread_switch(rtems_tcb *a, rtems_tcb *b)
 static void one_thread_begin(rtems_tcb *a)
 {
   assert_static_order(1);
+  assert_normal_thread_context();
 }
 
 static void one_thread_exitted(rtems_tcb *a)
 {
   assert_static_order(1);
+  assert_normal_thread_context();
 }
 
 static void one_fatal(
@@ -153,27 +212,32 @@ static void one_fatal(
 static void one_thread_terminate(rtems_tcb *a)
 {
   assert_static_order(1);
+  assert_life_protected_thread_context();
 }
 
 static bool two_thread_create(rtems_tcb *a, rtems_tcb *b)
 {
   assert_forward_order(2);
+  assert_allocator_protected_thread_context();
   return true;
 }
 
 static void two_thread_start(rtems_tcb *a, rtems_tcb *b)
 {
   assert_forward_order(2);
+  assert_thread_dispatch_disabled_context();
 }
 
 static void two_thread_restart(rtems_tcb *a, rtems_tcb *b)
 {
   assert_static_order(2);
+  assert_life_protected_thread_context();
 }
 
 static void two_thread_delete(rtems_tcb *a, rtems_tcb *b)
 {
   assert_reverse_order(2);
+  assert_allocator_protected_thread_context();
 }
 
 static void two_thread_switch(rtems_tcb *a, rtems_tcb *b)
@@ -184,11 +248,13 @@ static void two_thread_switch(rtems_tcb *a, rtems_tcb *b)
 static void two_thread_begin(rtems_tcb *a)
 {
   assert_forward_order(2);
+  assert_normal_thread_context();
 }
 
 static void two_thread_exitted(rtems_tcb *a)
 {
   assert_forward_order(2);
+  assert_normal_thread_context();
 }
 
 static void two_fatal(
@@ -207,27 +273,32 @@ static void two_fatal(
 static void two_thread_terminate(rtems_tcb *a)
 {
   assert_forward_order(2);
+  assert_life_protected_thread_context();
 }
 
 static bool three_thread_create(rtems_tcb *a, rtems_tcb *b)
 {
   assert_forward_order(3);
+  assert_allocator_protected_thread_context();
   return true;
 }
 
 static void three_thread_start(rtems_tcb *a, rtems_tcb *b)
 {
   assert_forward_order(3);
+  assert_thread_dispatch_disabled_context();
 }
 
 static void three_thread_restart(rtems_tcb *a, rtems_tcb *b)
 {
   assert_static_order(3);
+  assert_life_protected_thread_context();
 }
 
 static void three_thread_delete(rtems_tcb *a, rtems_tcb *b)
 {
   assert_reverse_order(3);
+  assert_allocator_protected_thread_context();
 }
 
 static void three_thread_switch(rtems_tcb *a, rtems_tcb *b)
@@ -238,11 +309,13 @@ static void three_thread_switch(rtems_tcb *a, rtems_tcb *b)
 static void three_thread_begin(rtems_tcb *a)
 {
   assert_forward_order(3);
+  assert_normal_thread_context();
 }
 
 static void three_thread_exitted(rtems_tcb *a)
 {
   assert_forward_order(3);
+  assert_normal_thread_context();
 }
 
 static void three_fatal(
@@ -259,6 +332,7 @@ static void three_fatal(
 static void three_thread_terminate(rtems_tcb *a)
 {
   assert_forward_order(3);
+  assert_life_protected_thread_context();
 }
 
 #define ZERO \
-- 
1.8.4.5



More information about the devel mailing list