[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