<div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Aug 21, 2020 at 6:51 AM Sebastian Huber <<a href="mailto:sebastian.huber@embedded-brains.de">sebastian.huber@embedded-brains.de</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">In contrast to rtems_task_create() this function creates a task with a<br>
user-provided task storage area.<br></blockquote><div><br></div><div>And all the creation parameters are in a structure which this log doesn't mention.</div><div><br></div><div>How is the user supposed to know how large the "task storage area" should be</div><div>The sp01 modifications seem to be a bit deceptive because the area is just declared</div><div>in terms of stack size. I would expect some user facing macros that capture the</div><div>size required for a non-FP and FP task. If FP is all tasks, then both would give</div><div>the same base value. Perhaps even take the requested stack size.</div><div><br></div><div>How does the user account for any memory that is needed for alignment? </div><div>Declaring a byte array is almost certainly not aligned sufficiently for a</div><div>structure with larger elements and the stack itself may need to be cache</div><div>line size aligned.</div><div><br></div><div>I spotted multiple places in this patch where variables and parameters</div><div>are not aligned properly. </div><div><br></div><div>But more important than formatting, I think the user facing part is too error </div><div>prone as it appears to be defined. It still counts as a user facing task which </div><div>means confdefs.h will include it in its stack calculations and that is used</div><div>to reserve memory which will never be used. Similarly maximum tasks</div><div>is used to reserve work space memory for various structures. </div><div><br></div><div>I don't think this one is ready. It needs API discussion more than basic</div><div>feature discussion.</div><div><br></div><div>--joel</div><div><br></div><div><br><br><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
Close #3959.<br>
---<br>
cpukit/Makefile.am | 1 +<br>
cpukit/include/rtems/rtems/tasks.h | 65 ++++++<br>
cpukit/include/rtems/rtems/tasksimpl.h | 11 +<br>
cpukit/rtems/src/taskbuild.c | 273 ++++++++++++++++++++++++<br>
cpukit/rtems/src/taskcreate.c | 274 +++++--------------------<br>
testsuites/sptests/sp01/init.c | 22 +-<br>
testsuites/sptests/sp01/sp01.doc | 1 +<br>
testsuites/sptests/sp01/system.h | 2 +-<br>
8 files changed, 413 insertions(+), 236 deletions(-)<br>
create mode 100644 cpukit/rtems/src/taskbuild.c<br>
<br>
diff --git a/cpukit/Makefile.am b/cpukit/Makefile.am<br>
index bc56822cf8..e382478eac 100644<br>
--- a/cpukit/Makefile.am<br>
+++ b/cpukit/Makefile.am<br>
@@ -785,6 +785,7 @@ librtemscpu_a_SOURCES += rtems/src/statustext.c<br>
librtemscpu_a_SOURCES += rtems/src/statustoerrno.c<br>
librtemscpu_a_SOURCES += rtems/src/systemeventreceive.c<br>
librtemscpu_a_SOURCES += rtems/src/systemeventsend.c<br>
+librtemscpu_a_SOURCES += rtems/src/taskbuild.c<br>
librtemscpu_a_SOURCES += rtems/src/taskcreate.c<br>
librtemscpu_a_SOURCES += rtems/src/taskdelete.c<br>
librtemscpu_a_SOURCES += rtems/src/taskexit.c<br>
diff --git a/cpukit/include/rtems/rtems/tasks.h b/cpukit/include/rtems/rtems/tasks.h<br>
index 12c323e60e..dff811686a 100644<br>
--- a/cpukit/include/rtems/rtems/tasks.h<br>
+++ b/cpukit/include/rtems/rtems/tasks.h<br>
@@ -164,6 +164,71 @@ rtems_status_code rtems_task_create(<br>
rtems_id *id<br>
);<br>
<br>
+/**<br>
+ * @brief This structure defines the configuration of a task to build with<br>
+ * rtems_task_build().<br>
+ */<br>
+typedef struct {<br>
+ /**<br>
+ * @brief This member defines the name of the task.<br>
+ */<br>
+ rtems_name name;<br>
+<br>
+ /**<br>
+ * @brief This member defines initial priority of the task.<br>
+ */<br>
+ rtems_task_priority initial_priority;<br>
+<br>
+ /**<br>
+ * @brief This member shall point to the task storage area begin.<br>
+ *<br>
+ * The task storage area will contain the task stack, the thread-local<br>
+ * storage, and, on some architectures, the floating-point context.<br>
+ */<br>
+ void *storage_area;<br>
+<br>
+ /**<br>
+ * @brief This member defines size of the task storage area in bytes.<br>
+ */<br>
+ size_t storage_size;<br>
+<br>
+ /**<br>
+ * @brief This member defines the optional handler to free the task storage<br>
+ * area.<br>
+ *<br>
+ * It may be NULL.<br>
+ */<br>
+ void ( *storage_free )( void * );<br>
+<br>
+ /**<br>
+ * @brief This member defines the initial modes of the task.<br>
+ */<br>
+ rtems_mode initial_modes;<br>
+<br>
+ /**<br>
+ * @brief This member defines the attributes of the task.<br>
+ */<br>
+ rtems_attribute attributes;<br>
+} rtems_task_config;<br>
+<br>
+/**<br>
+ * @brief Builds a task according to the specified configuration.<br>
+ *<br>
+ * @param config The task configuration.<br>
+ * @param[out] id The task identifier of the new task.<br>
+ *<br>
+ * @retval RTEMS_SUCCESSFUL Successful operation.<br>
+ * @retval RTEMS_INVALID_ADDRESS The id parameter is @c NULL.<br>
+ * @retval RTEMS_INVALID_NAME The task name is invalid.<br>
+ * @retval RTEMS_INVALID_PRIORITY The initial priority of the task is invalid.<br>
+ * @retval RTEMS_TOO_MANY No task is available.<br>
+ * @retval RTEMS_UNSATISFIED A task create extension failed.<br>
+ */<br>
+rtems_status_code rtems_task_build(<br>
+ const rtems_task_config *config,<br>
+ rtems_id *id<br>
+);<br>
+<br>
/**<br>
* @brief RTEMS Task Name to Id<br>
*<br>
diff --git a/cpukit/include/rtems/rtems/tasksimpl.h b/cpukit/include/rtems/rtems/tasksimpl.h<br>
index c9544f8c27..b1c1f38899 100644<br>
--- a/cpukit/include/rtems/rtems/tasksimpl.h<br>
+++ b/cpukit/include/rtems/rtems/tasksimpl.h<br>
@@ -42,6 +42,17 @@ extern "C" {<br>
*/<br>
void _RTEMS_tasks_Initialize_user_tasks( void );<br>
<br>
+typedef void ( *RTEMS_tasks_Prepare_stack )(<br>
+ Thread_Configuration *,<br>
+ const rtems_task_config *<br>
+);<br>
+<br>
+rtems_status_code _RTEMS_tasks_Build(<br>
+ const rtems_task_config *config,<br>
+ rtems_id *id,<br>
+ RTEMS_tasks_Prepare_stack prepare_stack<br>
+);<br>
+<br>
RTEMS_INLINE_ROUTINE Thread_Control *_RTEMS_tasks_Allocate(void)<br>
{<br>
_Objects_Allocator_lock();<br>
diff --git a/cpukit/rtems/src/taskbuild.c b/cpukit/rtems/src/taskbuild.c<br>
new file mode 100644<br>
index 0000000000..28f9f536f6<br>
--- /dev/null<br>
+++ b/cpukit/rtems/src/taskbuild.c<br>
@@ -0,0 +1,273 @@<br>
+/**<br>
+ * @file<br>
+ *<br>
+ * @brief RTEMS Task Create<br>
+ * @ingroup ClassicTasks<br>
+ */<br>
+<br>
+/*<br>
+ * COPYRIGHT (c) 1989-2014,2016.<br>
+ * On-Line Applications Research Corporation (OAR).<br>
+ *<br>
+ * The license and distribution terms for this file may be<br>
+ * found in the file LICENSE in this distribution or at<br>
+ * <a href="http://www.rtems.org/license/LICENSE" rel="noreferrer" target="_blank">http://www.rtems.org/license/LICENSE</a>.<br>
+ */<br>
+<br>
+#ifdef HAVE_CONFIG_H<br>
+#include "config.h"<br>
+#endif<br>
+<br>
+#include <rtems/rtems/tasksimpl.h><br>
+#include <rtems/rtems/attrimpl.h><br>
+#include <rtems/rtems/eventimpl.h><br>
+#include <rtems/rtems/modesimpl.h><br>
+#include <rtems/rtems/support.h><br>
+#include <rtems/score/apimutex.h><br>
+#include <rtems/score/schedulerimpl.h><br>
+#include <rtems/score/stackimpl.h><br>
+#include <rtems/score/sysstate.h><br>
+#include <rtems/score/threadimpl.h><br>
+#include <rtems/score/userextimpl.h><br>
+#include <rtems/sysinit.h><br>
+<br>
+#include <string.h><br>
+<br>
+static void _RTEMS_tasks_Prepare_user_stack(<br>
+ Thread_Configuration *thread_config,<br>
+ const rtems_task_config *config<br>
+)<br>
+{<br>
+ thread_config->stack_size = config->storage_size;<br>
+ thread_config->stack_area = config->storage_area;<br>
+<br>
+ if ( config->storage_free != NULL ) {<br>
+ thread_config->stack_free = config->storage_free;<br>
+ } else {<br>
+ thread_config->stack_free = _Stack_Free_nothing;<br>
+ }<br>
+}<br>
+<br>
+rtems_status_code rtems_task_build(<br>
+ const rtems_task_config *config,<br>
+ rtems_id *id<br>
+)<br>
+{<br>
+ return _RTEMS_tasks_Build( config, id, _RTEMS_tasks_Prepare_user_stack );<br>
+}<br>
+<br>
+rtems_status_code _RTEMS_tasks_Build(<br>
+ const rtems_task_config *config,<br>
+ rtems_id *id,<br>
+ RTEMS_tasks_Prepare_stack prepare_stack<br>
+)<br>
+{<br>
+ Thread_Control *the_thread;<br>
+ Thread_Configuration thread_config;<br>
+#if defined(RTEMS_MULTIPROCESSING)<br>
+ Objects_MP_Control *the_global_object = NULL;<br>
+ bool is_global;<br>
+#endif<br>
+ bool status;<br>
+ rtems_attribute attributes;<br>
+ bool valid;<br>
+ RTEMS_API_Control *api;<br>
+ ASR_Information *asr;<br>
+<br>
+ if ( !id )<br>
+ return RTEMS_INVALID_ADDRESS;<br>
+<br>
+ if ( !rtems_is_name_valid( config->name ) )<br>
+ return RTEMS_INVALID_NAME;<br>
+<br>
+ /*<br>
+ * Core Thread Initialize insures we get the minimum amount of<br>
+ * stack space.<br>
+ */<br>
+<br>
+ /*<br>
+ * Fix the attribute set to match the attributes which<br>
+ * this processor (1) requires and (2) is able to support.<br>
+ * First add in the required flags for attributes<br>
+ * Typically this might include FP if the platform<br>
+ * or application required all tasks to be fp aware.<br>
+ * Then turn off the requested bits which are not supported.<br>
+ */<br>
+<br>
+ attributes = _Attributes_Set( config->attributes, ATTRIBUTES_REQUIRED );<br>
+ attributes = _Attributes_Clear( attributes, ATTRIBUTES_NOT_SUPPORTED );<br>
+<br>
+ memset( &thread_config, 0, sizeof( thread_config ) );<br>
+ thread_config.budget_algorithm = _Modes_Is_timeslice( config->initial_modes ) ?<br>
+ THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE<br>
+ : THREAD_CPU_BUDGET_ALGORITHM_NONE,<br>
+ thread_config.isr_level = _Modes_Get_interrupt_level( config->initial_modes );<br>
+ thread_config.name.name_u32 = config->name;<br>
+ thread_config.is_fp = _Attributes_Is_floating_point( attributes );<br>
+ thread_config.is_preemptible = _Modes_Is_preempt( config->initial_modes );<br>
+<br>
+ /*<br>
+ * Validate the RTEMS API priority and convert it to the core priority range.<br>
+ */<br>
+<br>
+ if ( !_Attributes_Is_system_task( attributes ) ) {<br>
+ if ( config->initial_priority == PRIORITY_MINIMUM ) {<br>
+ return RTEMS_INVALID_PRIORITY;<br>
+ }<br>
+ }<br>
+<br>
+ thread_config.scheduler =<br>
+ _Thread_Scheduler_get_home( _Thread_Get_executing() );<br>
+<br>
+ thread_config.priority = _RTEMS_Priority_To_core(<br>
+ thread_config.scheduler,<br>
+ config->initial_priority,<br>
+ &valid<br>
+ );<br>
+ if ( !valid ) {<br>
+ return RTEMS_INVALID_PRIORITY;<br>
+ }<br>
+<br>
+#if defined(RTEMS_MULTIPROCESSING)<br>
+ if ( !_System_state_Is_multiprocessing ) {<br>
+ attributes = _Attributes_Clear( attributes, RTEMS_GLOBAL );<br>
+ }<br>
+<br>
+ is_global = _Attributes_Is_global( attributes );<br>
+#endif<br>
+<br>
+ /*<br>
+ * Allocate the thread control block and -- if the task is global --<br>
+ * allocate a global object control block.<br>
+ *<br>
+ * NOTE: This routine does not use the combined allocate and open<br>
+ * global object routine (_Objects_MP_Allocate_and_open) because<br>
+ * this results in a lack of control over when memory is allocated<br>
+ * and can be freed in the event of an error.<br>
+ */<br>
+ the_thread = _RTEMS_tasks_Allocate();<br>
+<br>
+ if ( !the_thread ) {<br>
+ _Objects_Allocator_unlock();<br>
+ return RTEMS_TOO_MANY;<br>
+ }<br>
+<br>
+#if defined(RTEMS_MULTIPROCESSING)<br>
+ if ( is_global ) {<br>
+ the_global_object = _Objects_MP_Allocate_global_object();<br>
+<br>
+ if ( _Objects_MP_Is_null_global_object( the_global_object ) ) {<br>
+ _RTEMS_tasks_Free( the_thread );<br>
+ _Objects_Allocator_unlock();<br>
+ return RTEMS_TOO_MANY;<br>
+ }<br>
+ }<br>
+#endif<br>
+<br>
+ ( *prepare_stack )( &thread_config, config );<br>
+ status = ( thread_config.stack_area != NULL );<br>
+<br>
+ /*<br>
+ * Initialize the core thread for this task.<br>
+ */<br>
+<br>
+ if ( status ) {<br>
+ status = _Thread_Initialize(<br>
+ &_RTEMS_tasks_Information,<br>
+ the_thread,<br>
+ &thread_config<br>
+ );<br>
+ }<br>
+<br>
+ if ( !status ) {<br>
+#if defined(RTEMS_MULTIPROCESSING)<br>
+ if ( is_global )<br>
+ _Objects_MP_Free_global_object( the_global_object );<br>
+#endif<br>
+ _RTEMS_tasks_Free( the_thread );<br>
+ _Objects_Allocator_unlock();<br>
+ return RTEMS_UNSATISFIED;<br>
+ }<br>
+<br>
+ api = the_thread->API_Extensions[ THREAD_API_RTEMS ];<br>
+ asr = &api->Signal;<br>
+<br>
+ asr->is_enabled = !_Modes_Is_asr_disabled( config->initial_modes );<br>
+<br>
+ *id = the_thread->Object.id;<br>
+<br>
+#if defined(RTEMS_MULTIPROCESSING)<br>
+ the_thread->is_global = is_global;<br>
+ if ( is_global ) {<br>
+<br>
+ _Objects_MP_Open(<br>
+ &_RTEMS_tasks_Information.Objects,<br>
+ the_global_object,<br>
+ config->name,<br>
+ the_thread->Object.id<br>
+ );<br>
+<br>
+ _RTEMS_tasks_MP_Send_process_packet(<br>
+ RTEMS_TASKS_MP_ANNOUNCE_CREATE,<br>
+ the_thread->Object.id,<br>
+ config->name<br>
+ );<br>
+<br>
+ }<br>
+#endif<br>
+<br>
+ _Objects_Allocator_unlock();<br>
+ return RTEMS_SUCCESSFUL;<br>
+}<br>
+<br>
+static void _RTEMS_tasks_Start_extension(<br>
+ Thread_Control *executing,<br>
+ Thread_Control *started<br>
+)<br>
+{<br>
+ RTEMS_API_Control *api;<br>
+<br>
+ api = started->API_Extensions[ THREAD_API_RTEMS ];<br>
+<br>
+ _Event_Initialize( &api->Event );<br>
+ _Event_Initialize( &api->System_event );<br>
+}<br>
+<br>
+#if defined(RTEMS_MULTIPROCESSING)<br>
+static void _RTEMS_tasks_Terminate_extension( Thread_Control *executing )<br>
+{<br>
+ if ( executing->is_global ) {<br>
+ _Objects_MP_Close(<br>
+ &_RTEMS_tasks_Information.Objects,<br>
+ executing->Object.id<br>
+ );<br>
+ _RTEMS_tasks_MP_Send_process_packet(<br>
+ RTEMS_TASKS_MP_ANNOUNCE_DELETE,<br>
+ executing->Object.id,<br>
+ 0 /* Not used */<br>
+ );<br>
+ }<br>
+}<br>
+#endif<br>
+<br>
+static User_extensions_Control _RTEMS_tasks_User_extensions = {<br>
+ .Callouts = {<br>
+#if defined(RTEMS_MULTIPROCESSING)<br>
+ .thread_terminate = _RTEMS_tasks_Terminate_extension,<br>
+#endif<br>
+ .thread_start = _RTEMS_tasks_Start_extension,<br>
+ .thread_restart = _RTEMS_tasks_Start_extension<br>
+ }<br>
+};<br>
+<br>
+static void _RTEMS_tasks_Manager_initialization( void )<br>
+{<br>
+ _Thread_Initialize_information( &_RTEMS_tasks_Information );<br>
+ _User_extensions_Add_API_set( &_RTEMS_tasks_User_extensions );<br>
+}<br>
+<br>
+RTEMS_SYSINIT_ITEM(<br>
+ _RTEMS_tasks_Manager_initialization,<br>
+ RTEMS_SYSINIT_CLASSIC_TASKS,<br>
+ RTEMS_SYSINIT_ORDER_MIDDLE<br>
+);<br>
diff --git a/cpukit/rtems/src/taskcreate.c b/cpukit/rtems/src/taskcreate.c<br>
index 5486ac9b6e..3a0badf285 100644<br>
--- a/cpukit/rtems/src/taskcreate.c<br>
+++ b/cpukit/rtems/src/taskcreate.c<br>
@@ -1,17 +1,36 @@<br>
+/* SPDX-License-Identifier: BSD-2-Clause */<br>
+<br>
/**<br>
- * @file<br>
+ * @file<br>
+ *<br>
+ * @ingroup ClassicTasks<br>
*<br>
- * @brief RTEMS Task Create<br>
- * @ingroup ClassicTasks<br>
+ * @brief RTEMS Task Create<br>
*/<br>
<br>
/*<br>
- * COPYRIGHT (c) 1989-2014,2016.<br>
- * On-Line Applications Research Corporation (OAR).<br>
+ * Copyright (C) 2020 embedded brains GmbH (<a href="http://www.embedded-brains.de" rel="noreferrer" target="_blank">http://www.embedded-brains.de</a>)<br>
*<br>
- * The license and distribution terms for this file may be<br>
- * found in the file LICENSE in this distribution or at<br>
- * <a href="http://www.rtems.org/license/LICENSE" rel="noreferrer" target="_blank">http://www.rtems.org/license/LICENSE</a>.<br>
+ * Redistribution and use in source and binary forms, with or without<br>
+ * modification, are permitted provided that the following conditions<br>
+ * are met:<br>
+ * 1. Redistributions of source code must retain the above copyright<br>
+ * notice, this list of conditions and the following disclaimer.<br>
+ * 2. Redistributions in binary form must reproduce the above copyright<br>
+ * notice, this list of conditions and the following disclaimer in the<br>
+ * documentation and/or other materials provided with the distribution.<br>
+ *<br>
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"<br>
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE<br>
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE<br>
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE<br>
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR<br>
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF<br>
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS<br>
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN<br>
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)<br>
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE<br>
+ * POSSIBILITY OF SUCH DAMAGE.<br>
*/<br>
<br>
#ifdef HAVE_CONFIG_H<br>
@@ -19,20 +38,24 @@<br>
#endif<br>
<br>
#include <rtems/rtems/tasksimpl.h><br>
-#include <rtems/rtems/attrimpl.h><br>
-#include <rtems/rtems/eventimpl.h><br>
-#include <rtems/rtems/modesimpl.h><br>
-#include <rtems/rtems/support.h><br>
-#include <rtems/score/apimutex.h><br>
-#include <rtems/score/schedulerimpl.h><br>
#include <rtems/score/stackimpl.h><br>
-#include <rtems/score/sysstate.h><br>
-#include <rtems/score/threadimpl.h><br>
-#include <rtems/score/userextimpl.h><br>
-#include <rtems/sysinit.h><br>
<br>
#include <string.h><br>
<br>
+static void _RTEMS_tasks_Allocate_and_prepare_stack(<br>
+ Thread_Configuration *thread_config,<br>
+ const rtems_task_config *config<br>
+)<br>
+{<br>
+ size_t size;<br>
+<br>
+ thread_config->stack_free = _Stack_Free;<br>
+ size = _Stack_Ensure_minimum( config->storage_size );<br>
+ size = _Stack_Extend_size( size, thread_config->is_fp );<br>
+ thread_config->stack_size = size;<br>
+ thread_config->stack_area = _Stack_Allocate( size );<br>
+}<br>
+<br>
rtems_status_code rtems_task_create(<br>
rtems_name name,<br>
rtems_task_priority initial_priority,<br>
@@ -42,215 +65,14 @@ rtems_status_code rtems_task_create(<br>
rtems_id *id<br>
)<br>
{<br>
- Thread_Control *the_thread;<br>
- Thread_Configuration config;<br>
-#if defined(RTEMS_MULTIPROCESSING)<br>
- Objects_MP_Control *the_global_object = NULL;<br>
- bool is_global;<br>
-#endif<br>
- bool status;<br>
- rtems_attribute the_attribute_set;<br>
- bool valid;<br>
- RTEMS_API_Control *api;<br>
- ASR_Information *asr;<br>
-<br>
- if ( !id )<br>
- return RTEMS_INVALID_ADDRESS;<br>
-<br>
- if ( !rtems_is_name_valid( name ) )<br>
- return RTEMS_INVALID_NAME;<br>
-<br>
- /*<br>
- * Core Thread Initialize insures we get the minimum amount of<br>
- * stack space.<br>
- */<br>
-<br>
- /*<br>
- * Fix the attribute set to match the attributes which<br>
- * this processor (1) requires and (2) is able to support.<br>
- * First add in the required flags for attribute_set<br>
- * Typically this might include FP if the platform<br>
- * or application required all tasks to be fp aware.<br>
- * Then turn off the requested bits which are not supported.<br>
- */<br>
-<br>
- the_attribute_set = _Attributes_Set( attribute_set, ATTRIBUTES_REQUIRED );<br>
- the_attribute_set =<br>
- _Attributes_Clear( the_attribute_set, ATTRIBUTES_NOT_SUPPORTED );<br>
+ rtems_task_config config;<br>
<br>
memset( &config, 0, sizeof( config ) );<br>
- config.budget_algorithm = _Modes_Is_timeslice( initial_modes ) ?<br>
- THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE<br>
- : THREAD_CPU_BUDGET_ALGORITHM_NONE,<br>
- config.isr_level = _Modes_Get_interrupt_level( initial_modes );<br>
- config.name.name_u32 = name;<br>
- config.is_fp = _Attributes_Is_floating_point( the_attribute_set );<br>
- config.is_preemptible = _Modes_Is_preempt( initial_modes );<br>
- config.stack_size = _Stack_Ensure_minimum( stack_size );<br>
- config.stack_size = _Stack_Extend_size( config.stack_size, config.is_fp );<br>
-<br>
- /*<br>
- * Validate the RTEMS API priority and convert it to the core priority range.<br>
- */<br>
-<br>
- if ( !_Attributes_Is_system_task( the_attribute_set ) ) {<br>
- if ( initial_priority == PRIORITY_MINIMUM ) {<br>
- return RTEMS_INVALID_PRIORITY;<br>
- }<br>
- }<br>
-<br>
- config.scheduler = _Thread_Scheduler_get_home( _Thread_Get_executing() );<br>
-<br>
- config.priority = _RTEMS_Priority_To_core(<br>
- config.scheduler,<br>
- initial_priority,<br>
- &valid<br>
- );<br>
- if ( !valid ) {<br>
- return RTEMS_INVALID_PRIORITY;<br>
- }<br>
-<br>
-#if defined(RTEMS_MULTIPROCESSING)<br>
- if ( !_System_state_Is_multiprocessing ) {<br>
- the_attribute_set = _Attributes_Clear( the_attribute_set, RTEMS_GLOBAL );<br>
- }<br>
-<br>
- is_global = _Attributes_Is_global( the_attribute_set );<br>
-#endif<br>
-<br>
- /*<br>
- * Allocate the thread control block and -- if the task is global --<br>
- * allocate a global object control block.<br>
- *<br>
- * NOTE: This routine does not use the combined allocate and open<br>
- * global object routine (_Objects_MP_Allocate_and_open) because<br>
- * this results in a lack of control over when memory is allocated<br>
- * and can be freed in the event of an error.<br>
- */<br>
- the_thread = _RTEMS_tasks_Allocate();<br>
-<br>
- if ( !the_thread ) {<br>
- _Objects_Allocator_unlock();<br>
- return RTEMS_TOO_MANY;<br>
- }<br>
-<br>
-#if defined(RTEMS_MULTIPROCESSING)<br>
- if ( is_global ) {<br>
- the_global_object = _Objects_MP_Allocate_global_object();<br>
-<br>
- if ( _Objects_MP_Is_null_global_object( the_global_object ) ) {<br>
- _RTEMS_tasks_Free( the_thread );<br>
- _Objects_Allocator_unlock();<br>
- return RTEMS_TOO_MANY;<br>
- }<br>
- }<br>
-#endif<br>
-<br>
- config.stack_free = _Stack_Free;<br>
- config.stack_area = _Stack_Allocate( config.stack_size );<br>
- status = ( config.stack_area != NULL );<br>
-<br>
- /*<br>
- * Initialize the core thread for this task.<br>
- */<br>
+ <a href="http://config.name" rel="noreferrer" target="_blank">config.name</a> = name;<br>
+ config.initial_priority = initial_priority;<br>
+ config.storage_size = stack_size;<br>
+ config.initial_modes = initial_modes;<br>
+ config.attributes = attribute_set;<br>
<br>
- if ( status ) {<br>
- status = _Thread_Initialize(<br>
- &_RTEMS_tasks_Information,<br>
- the_thread,<br>
- &config<br>
- );<br>
- }<br>
-<br>
- if ( !status ) {<br>
-#if defined(RTEMS_MULTIPROCESSING)<br>
- if ( is_global )<br>
- _Objects_MP_Free_global_object( the_global_object );<br>
-#endif<br>
- _RTEMS_tasks_Free( the_thread );<br>
- _Objects_Allocator_unlock();<br>
- return RTEMS_UNSATISFIED;<br>
- }<br>
-<br>
- api = the_thread->API_Extensions[ THREAD_API_RTEMS ];<br>
- asr = &api->Signal;<br>
-<br>
- asr->is_enabled = _Modes_Is_asr_disabled(initial_modes) ? false : true;<br>
-<br>
- *id = the_thread->Object.id;<br>
-<br>
-#if defined(RTEMS_MULTIPROCESSING)<br>
- the_thread->is_global = is_global;<br>
- if ( is_global ) {<br>
-<br>
- _Objects_MP_Open(<br>
- &_RTEMS_tasks_Information.Objects,<br>
- the_global_object,<br>
- name,<br>
- the_thread->Object.id<br>
- );<br>
-<br>
- _RTEMS_tasks_MP_Send_process_packet(<br>
- RTEMS_TASKS_MP_ANNOUNCE_CREATE,<br>
- the_thread->Object.id,<br>
- name<br>
- );<br>
-<br>
- }<br>
-#endif<br>
-<br>
- _Objects_Allocator_unlock();<br>
- return RTEMS_SUCCESSFUL;<br>
+ return _RTEMS_tasks_Build( &config, id, _RTEMS_tasks_Allocate_and_prepare_stack );<br>
}<br>
-<br>
-static void _RTEMS_tasks_Start_extension(<br>
- Thread_Control *executing,<br>
- Thread_Control *started<br>
-)<br>
-{<br>
- RTEMS_API_Control *api;<br>
-<br>
- api = started->API_Extensions[ THREAD_API_RTEMS ];<br>
-<br>
- _Event_Initialize( &api->Event );<br>
- _Event_Initialize( &api->System_event );<br>
-}<br>
-<br>
-#if defined(RTEMS_MULTIPROCESSING)<br>
-static void _RTEMS_tasks_Terminate_extension( Thread_Control *executing )<br>
-{<br>
- if ( executing->is_global ) {<br>
- _Objects_MP_Close(<br>
- &_RTEMS_tasks_Information.Objects,<br>
- executing->Object.id<br>
- );<br>
- _RTEMS_tasks_MP_Send_process_packet(<br>
- RTEMS_TASKS_MP_ANNOUNCE_DELETE,<br>
- executing->Object.id,<br>
- 0 /* Not used */<br>
- );<br>
- }<br>
-}<br>
-#endif<br>
-<br>
-static User_extensions_Control _RTEMS_tasks_User_extensions = {<br>
- .Callouts = {<br>
-#if defined(RTEMS_MULTIPROCESSING)<br>
- .thread_terminate = _RTEMS_tasks_Terminate_extension,<br>
-#endif<br>
- .thread_start = _RTEMS_tasks_Start_extension,<br>
- .thread_restart = _RTEMS_tasks_Start_extension<br>
- }<br>
-};<br>
-<br>
-static void _RTEMS_tasks_Manager_initialization( void )<br>
-{<br>
- _Thread_Initialize_information( &_RTEMS_tasks_Information );<br>
- _User_extensions_Add_API_set( &_RTEMS_tasks_User_extensions );<br>
-}<br>
-<br>
-RTEMS_SYSINIT_ITEM(<br>
- _RTEMS_tasks_Manager_initialization,<br>
- RTEMS_SYSINIT_CLASSIC_TASKS,<br>
- RTEMS_SYSINIT_ORDER_MIDDLE<br>
-);<br>
diff --git a/testsuites/sptests/sp01/init.c b/testsuites/sptests/sp01/init.c<br>
index 2719c84fc8..f25300e5bb 100644<br>
--- a/testsuites/sptests/sp01/init.c<br>
+++ b/testsuites/sptests/sp01/init.c<br>
@@ -16,6 +16,17 @@<br>
<br>
const char rtems_test_name[] = "SP 1";<br>
<br>
+static char Task_1_storage[ 2 * RTEMS_MINIMUM_STACK_SIZE ];<br>
+<br>
+static const rtems_task_config Task_1_config = {<br>
+ .name = rtems_build_name( 'T', 'A', '1', ' ' ),<br>
+ .initial_priority = 1,<br>
+ .storage_area = Task_1_storage,<br>
+ .storage_size = sizeof( Task_1_storage ),<br>
+ .initial_modes = RTEMS_DEFAULT_MODES,<br>
+ .attributes = RTEMS_DEFAULT_ATTRIBUTES<br>
+};<br>
+<br>
rtems_task Init(<br>
rtems_task_argument argument<br>
)<br>
@@ -30,15 +41,8 @@ rtems_task Init(<br>
status = rtems_clock_set( &time );<br>
directive_failed( status, "rtems_clock_set" );<br>
<br>
- status = rtems_task_create(<br>
- rtems_build_name( 'T', 'A', '1', ' ' ),<br>
- 1,<br>
- RTEMS_MINIMUM_STACK_SIZE * 2,<br>
- RTEMS_DEFAULT_MODES,<br>
- RTEMS_DEFAULT_ATTRIBUTES,<br>
- &id<br>
- );<br>
- directive_failed( status, "rtems_task_create of TA1" );<br>
+ status = rtems_task_build( &Task_1_config, &id );<br>
+ directive_failed( status, "rtems_task_build of TA1" );<br>
<br>
status = rtems_task_start( id, Task_1_through_3, 1 );<br>
directive_failed( status, "rtems_task_start of TA1" );<br>
diff --git a/testsuites/sptests/sp01/sp01.doc b/testsuites/sptests/sp01/sp01.doc<br>
index d7d9f5d902..62bbe956d3 100644<br>
--- a/testsuites/sptests/sp01/sp01.doc<br>
+++ b/testsuites/sptests/sp01/sp01.doc<br>
@@ -9,6 +9,7 @@<br>
test name: sp01<br>
<br>
directives:<br>
+ rtems_task_build<br>
rtems_task_create<br>
rtems_task_start<br>
rtems_task_wake_after<br>
diff --git a/testsuites/sptests/sp01/system.h b/testsuites/sptests/sp01/system.h<br>
index bde5328aa9..e2047b4d3a 100644<br>
--- a/testsuites/sptests/sp01/system.h<br>
+++ b/testsuites/sptests/sp01/system.h<br>
@@ -28,7 +28,7 @@ rtems_task Task_1_through_3(<br>
<br>
#define CONFIGURE_RTEMS_INIT_TASKS_TABLE<br>
<br>
-#define CONFIGURE_EXTRA_TASK_STACKS (4 * RTEMS_MINIMUM_STACK_SIZE)<br>
+#define CONFIGURE_EXTRA_TASK_STACKS (2 * RTEMS_MINIMUM_STACK_SIZE)<br>
#define CONFIGURE_MAXIMUM_TASKS 4<br>
<br>
#include <rtems/confdefs.h><br>
-- <br>
2.26.2<br>
<br>
_______________________________________________<br>
devel mailing list<br>
<a href="mailto:devel@rtems.org" target="_blank">devel@rtems.org</a><br>
<a href="http://lists.rtems.org/mailman/listinfo/devel" rel="noreferrer" target="_blank">http://lists.rtems.org/mailman/listinfo/devel</a><br>
</blockquote></div></div>