[PATCH 7/7] rtems: Add rtems_task_build()

Joel Sherrill joel at rtems.org
Mon Aug 31 21:15:23 UTC 2020


On Fri, Aug 21, 2020 at 6:51 AM Sebastian Huber <
sebastian.huber at embedded-brains.de> wrote:

> In contrast to rtems_task_create() this function creates a task with a
> user-provided task storage area.
>

And all the creation parameters are in a structure which this log doesn't
mention.

How is the user supposed to know how large the "task storage area" should be
The sp01 modifications seem to be a bit deceptive because the area is just
declared
in terms of stack size. I would expect some user facing macros that capture
the
size required for a non-FP and FP task. If FP is all tasks, then both would
give
the same base value. Perhaps even take the requested stack size.

How does the user account for any memory that is needed for alignment?
Declaring a byte array is almost certainly not aligned sufficiently for a
structure with larger elements and the stack itself may need to be cache
line size aligned.

I spotted multiple places in this patch where variables and parameters
are not aligned properly.

But more important than formatting, I think the user facing part is too
error
prone as it appears to be defined. It still counts as a user facing task
which
means confdefs.h will include it in its stack calculations and that is used
to reserve memory which will never be used. Similarly maximum tasks
is used to reserve work space memory for various structures.

I don't think this one is ready. It needs API discussion more than basic
feature discussion.

--joel





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


More information about the devel mailing list