[PATCH] rtems: Generate <rtems/extension.h>

Sebastian Huber sebastian.huber at embedded-brains.de
Fri Sep 10 09:40:13 UTC 2021


Hello Chris,

thanks for the review.

On 10/09/2021 10:55, Chris Johns wrote:
> Nice set of changes. My comments are below ....
> 
> On 10/9/21 6:11 pm, Sebastian Huber wrote:
>> Remove the duplicated description which is an out dated copy and paste
>> from the Classic API Guide.  Instead, thoroughly document the individual
>> extensions.
>>
>> Change license to BSD-2-Clause according to file histories and
>> documentation re-licensing agreement.
>>
>> Update #3899.
>> Update #3993.
>> ---
>>   cpukit/include/rtems/extension.h | 758 ++++++++++++++++++++++++-------
>>   1 file changed, 583 insertions(+), 175 deletions(-)
>>
>> diff --git a/cpukit/include/rtems/extension.h b/cpukit/include/rtems/extension.h
>> index 6f97ebe24c..ceb8eb9a1f 100644
>> --- a/cpukit/include/rtems/extension.h
>> +++ b/cpukit/include/rtems/extension.h
[...]
>> -typedef Internal_errors_Source rtems_fatal_source;
>> +/**
>> + * @ingroup RTEMSAPIClassicUserExt
>> + *
>> + * @brief Deletes the extension set.
>> + *
>> + * @param id is the extension set identifier.
>> + *
>> + * This directive deletes the extension set specified by ``id``.
>> + *
>> + * @retval ::RTEMS_SUCCESSFUL The requested operation was successful.
>> + *
>> + * @retval ::RTEMS_INVALID_ID There was no extension set associated with the
>> + *   identifier specified by ``id``.
>> + *
>> + * @par Notes
>> + * The ESCB for the deleted extension set is reclaimed by RTEMS.
> 
> ESCB? Can the definition to be local to here rather than needing to reach for
> the mouse, a browser, working internet link, a built doxygen .... :)

In the manuals you have a link to a glossary entry. This feature is not 
yet implemented for the Doxygen output.

> 
>> + *
>> + * @par Constraints
>> + * @parblock
>> + * The following constraints apply to this directive:
>> + *
>> + * * The directive may be called from within device driver initialization
>> + *   context.
> 
> Seem a little to ""specread"" .. maybe .. "during device driver initialization"?

This phrase is already used in a lot of directives. If we would like to 
change this, then this should be done in a separate patch set:

https://git.rtems.org/rtems-central/tree/spec/constraint/directive-ctx-devinit.yml

> 
>> + *
>> + * * The directive may be called from within task context.
> 
> Specread ?? ... "within task context" ... "within a task's context" ?

Same as above:

https://git.rtems.org/rtems-central/tree/spec/constraint/directive-ctx-task.yml

> 
>> + * * The directive may obtain and release the object allocator mutex.  This may
>> + *   cause the calling task to be preempted.
> 
> Block or preempted? I assume the task may be preempted before making the call?

The obtain will block the task, if the mutex is already owned by another 
task:

https://git.rtems.org/rtems-central/tree/spec/constraint/object-allocator.yml

This phrase should be improved in a separate patch set.

> 
> Do we assume task and thread and inter-changeable?

Yes, task is used mainly for Classic API tasks, and threads for tasks in 
general.

> 
>> + * * The calling task does not have to be the task that created the object.
>> + *   Any local task that knows the object identifier can delete the object.
>> + * @endparblock
>> + */
>> +rtems_status_code rtems_extension_delete( rtems_id id );
>> +
>> +/* Generated from spec:/rtems/userext/if/fatal */
>> +
>> +/**
>> + * @ingroup RTEMSAPIClassicUserExt
>> + *
>> + * @brief Fatal extensions are invoked when the system should terminate.
> 
> Should? Is it too late by the time the call is being made?

Yes, should, the fatal extension can prevent a system termination. An 
example is the POSIX task exitted extension.

> 
>> + *
>> + * @param source is the system termination source.  The source indicates the
>> + *   component which caused the system termination request, see
>> + *   ::rtems_fatal_source.  The system termination code may provide additional
>> + *   information related to the system termination request.
>> + *
>> + * @param always_set_to_false is a value equal to false.
>> + *
>> + * @param code is the system termination code.  This value must be interpreted
>> + *   with respect to the source.
>> + *
>> + * @par Notes
>> + * @parblock
>> + * The fatal extensions are invoked in extension forward order.
> 
> What does forward order mean?

This is in the glossary:

https://docs.rtems.org/branches/master/c-user/glossary.html#term-extension-forward-order

> 
>> + *
>> + * The fatal extension should be extremely careful with respect to the RTEMS
>> + * directives it calls.  Depending on the system termination source, the system
>> + * may be in an undefined and corrupt state.
> 
> Where is the list defined that is means "undefined and corrupt"?

You have to look at the system termination source documentation to 
figure this out.

> 
>> + *
>> + * It is recommended to register fatal extensions through initial extension
>> + * sets, see #CONFIGURE_INITIAL_EXTENSIONS.
>> + * @endparblock
>> + */
>> +typedef User_extensions_fatal_extension rtems_fatal_extension;
>> +
>> +/* Generated from spec:/rtems/userext/if/fatal-code */
>>   
>> +/**
>> + * @ingroup RTEMSAPIClassicUserExt
>> + *
>> + * @brief This integer type represents system termination codes.
>> + *
>> + * This integer type is large enough to store a 32-bit integer or a pointer.
>> + *
>> + * @par Notes
>> + * The interpretation of a system termination code depends on the system
>> + * termination source, see ::rtems_fatal_source.
>> + */
>>   typedef Internal_errors_t rtems_fatal_code;
>>   
>> +/* Generated from spec:/rtems/userext/if/fatal-source */
>> +
>> +/**
>> + * @ingroup RTEMSAPIClassicUserExt
>> + *
>> + * @brief This enumeration represents system termination sources.
>> + *
>> + * @par Notes
>> + * The system termination code may provide additional information depending on
>> + * the system termination source, see ::rtems_fatal_code.
>> + */
>> +typedef Internal_errors_Source rtems_fatal_source;
>> +
>> +/* Generated from spec:/rtems/userext/if/ident */
>> +
>>   /**
>> - * @brief Creates an extension set object.
>> + * @ingroup RTEMSAPIClassicUserExt
>> + *
>> + * @brief Identifies an extension set by the object name.
>> + *
>> + * @param name is the object name to look up.
>> + *
>> + * @param[out] id is the pointer to an ::rtems_id object.  When the directive
>> + *   call is successful, the object identifier of an object with the specified
>> + *   name will be stored in this object.
>> + *
>> + * This directive obtains an extension set identifier associated with the
>> + * extension set name specified in ``name``.
>> + *
>> + * @retval ::RTEMS_SUCCESSFUL The requested operation was successful.
>> + *
>> + * @retval ::RTEMS_INVALID_ADDRESS The ``id`` parameter was NULL.
>> + *
>> + * @retval ::RTEMS_INVALID_NAME The ``name`` parameter was 0.
>> + *
>> + * @retval ::RTEMS_INVALID_NAME There was no object with the specified name on
>> + *   the local node.
>>    *
>> - * This directive creates a extension set object from the extension table
>> - * @a extension_table.  The assigned extension set identifier is returned in
>> - * @a id.  The identifier is used to access this extension set in other
>> - * extension set related directives.  The name @a name will be assigned to the
>> - * extension set object.
>> + * @par Notes
>> + * @parblock
>> + * If the extension set name is not unique, then the extension set identifier
>> + * will match the first extension set with that name in the search order.
>> + * However, this extension set identifier is not guaranteed to correspond to
>> + * the desired extension set.
> 
> If the extension set name is not unique, then the extension set identifier
> will match the first extension set with that name in the search order
> and the extension set identifier is not guaranteed to correspond to
> the desired extension set.
> 
> ?

Yes, we change change this phrase, however, this is used in all the 
object identification directives. So, this should be done in a separate 
patch set.

> 
> 
> 
>> + *
>> + * The objects are searched from lowest to the highest index.  Only the local
>> + * node is searched.
>> + *
>> + * The extension set identifier is used with other extension related directives
>> + * to access the extension set.
>> + * @endparblock
>> + *
>> + * @par Constraints
>> + * @parblock
>> + * The following constraints apply to this directive:
>> + *
>> + * * The directive may be called from within device driver initialization
>> + *   context.
>> + *
>> + * * The directive will not cause the calling task to be preempted.
> 
> As above.

This is the generic phrase that a directive will perform a scheduler 
operation:

https://git.rtems.org/rtems-central/tree/spec/constraint/directive-no-preempt.yml

> 
>> + * @endparblock
>> + */
>> +rtems_status_code rtems_extension_ident( rtems_name name, rtems_id *id );
>> +
>> +/* Generated from spec:/rtems/userext/if/table */
>> +
>> +/**
>> + * @ingroup RTEMSAPIClassicUserExt
>> + *
>> + * @brief The extensions table contains a set of extensions which may be
>> + *   registered in the system through the #CONFIGURE_INITIAL_EXTENSIONS
>> + *   application configuration option or the rtems_extension_create()
>> + *   directive.
>> + */
>> +typedef User_extensions_Table rtems_extensions_table;
>> +
>> +/* Generated from spec:/rtems/userext/if/create */
>> +
>> +/**
>> + * @ingroup RTEMSAPIClassicUserExt
>> + *
>> + * @brief Creates an extension set.
>> + *
>> + * @param name is the object name of the extension set.
>> + *
>> + * @param extension_table is the table with the extensions to be used by the
>> + *   extension set.> + *
>> + * @param[out] id is the pointer to an ::rtems_id object.  When the directive
>> + *   call is successful, the identifier of the created extension set will be
>> + *   stored in this object.
>> + *
>> + * This directive creates an extension set which resides on the local node.
>> + * The extension set has the user-defined object name specified in ``name``.
>> + * The assigned object identifier is returned in ``id``.  This identifier is
>> + * used to access the extension set with other extension set related
>> + * directives.
>> + *
>> + * The extension set is initialized using the extension table specified in
>> + * ``extension_table``.
>> + *
>> + * @retval ::RTEMS_SUCCESSFUL The requested operation was successful.
>> + *
>> + * @retval ::RTEMS_INVALID_NAME The ``name`` parameter was invalid.
>> + *
>> + * @retval ::RTEMS_INVALID_ADDRESS The ``extension_table`` parameter was NULL.
>> + *
>> + * @retval ::RTEMS_INVALID_ADDRESS The ``id`` parameter was NULL.
>> + *
>> + * @retval ::RTEMS_TOO_MANY There was no inactive object available to create an
>> + *   extension set.  The number of extension sets available to the application
>> + *   is configured through the #CONFIGURE_MAXIMUM_USER_EXTENSIONS application
>> + *   configuration option.
>> + *
>> + * @par Notes
>> + * @parblock
>> + * The user-provided extension set table is not used after the return of the
>> + * directive.
>>    *
>>    * Newly created extension sets are immediately installed and are invoked upon
>>    * the next system event supporting an extension.
> 
> As a set? That is all handlers provided are active at the same time?

All except the task switch extension.

> 
>> - * This directive will not cause the calling task to be preempted.
>> + * An alternative to dynamically created extension sets are initial extensions,
>> + * see #CONFIGURE_INITIAL_EXTENSIONS.  Initial extensions are recommended for
>> + * extension sets which provide a fatal error extension.
>> + *
>> + * For control and maintenance of the extension set, RTEMS allocates a ESCB
>> + * from the local ESCB free pool and initializes it.
>> + * @endparblock
>> + *
>> + * @par Constraints
>> + * @parblock
>> + * The following constraints apply to this directive:
>>    *
>> - * @retval RTEMS_SUCCESSFUL Extension set created successfully.
>> - * @retval RTEMS_INVALID_ADDRESS Identifier pointer is @c NULL.
>> - * @retval RTEMS_INVALID_NAME Invalid extension set name.
>> - * @retval RTEMS_TOO_MANY Too many extension sets created.
>> + * * The directive may be called from within device driver initialization
>> + *   context.
>> + *
>> + * * The directive may be called from within task context.
>> + *
>> + * * The directive may obtain and release the object allocator mutex.  This may
>> + *   cause the calling task to be preempted.
>> + *
>> + * * The number of extension sets available to the application is configured
>> + *   through the #CONFIGURE_MAXIMUM_USER_EXTENSIONS application configuration
>> + *   option.
>> + * @endparblock
>>    */
> 
> Is having handlers entries set to NULL discussed? That is specific tables for
> unique non-overlapping functions?

No, I will add this.

> 
>>   rtems_status_code rtems_extension_create(
>>     rtems_name                    name,
>> @@ -192,47 +313,334 @@ rtems_status_code rtems_extension_create(
>>     rtems_id                     *id
>>   );
>>   
>> +/* Generated from spec:/rtems/userext/if/task-begin */
>> +
>>   /**
>> - * @brief Identifies an extension set object by a name.
>> + * @ingroup RTEMSAPIClassicUserExt
>> + *
>> + * @brief Task begin extensions are invoked when a task begins execution.
>>    *
>> - * This directive obtains an extension set identifier in @a id associated with
>> - * the extension set name @a name. If the extension set name is not unique,
>> - * then the extension set identifier will match one of the extension sets with
>> - * that name.  However, this extension set identifier is not guaranteed to
>> - * correspond to the desired extension set. The extension set identifier is
>> - * used to access this extension set in other extension set related directives.
>> + * @param executing is the TCB of the executing thread.
>>    *
>> - * This directive will not cause the calling task to be preempted.
>> + * @par Notes
>> + * @parblock
>> + * The task begin extensions are invoked in extension forward order.
>>    *
>> - * @retval RTEMS_SUCCESSFUL Extension set identified successfully.
>> - * @retval RTEMS_INVALID_ADDRESS Identifier pointer is @c NULL.
>> - * @retval RTEMS_INVALID_NAME Extension set name not found or invalid name.
>> + * Task begin extensions are invoked with thread dispatching enabled.  This
>> + * allows the use of dynamic memory allocation, creation of POSIX keys, and use
>> + * of C++ thread-local storage.  Blocking synchronization primitives are
>> + * allowed also.
>> + *
>> + * The task begin extensions are invoked before the global construction.
> 
> Construction of what?

This is the term used by the Classic API Guide:

https://docs.rtems.org/branches/master/c-user/initialization/operations.html#global-construction

> 
>> + *
>> + * The task begin extensions may be called as a result of a task restart
>> + * through rtems_task_restart().
>> + * @endparblock
>> + *
>> + * @par Constraints
>> + * @parblock
>> + * The following constraints apply to functions of this type:
>> + *
>> + * * Thread dispatching is enabled.
>> + *
>> + * * The executing thread is not the owner of the object allocator mutex.
>> + * @endparblock
>>    */
>> -rtems_status_code rtems_extension_ident(
>> -  rtems_name  name,
>> -  rtems_id   *id
>> -);
>> +typedef User_extensions_thread_begin_extension rtems_task_begin_extension;
>> +
>> +/* Generated from spec:/rtems/userext/if/task-create */
>>   
>>   /**
>> - * @brief Deletes an extension set object specified by the identifier @a id.
>> + * @ingroup RTEMSAPIClassicUserExt
>> + *
>> + * @brief Task create extensions are invoked when a task is created.
>> + *
>> + * @param executing is the TCB of the executing thread.  When the idle thread
>> + *   is created, the executing thread is equal to NULL.
>> + *
>> + * @param created is the TCB of the created thread.
>> + *
>> + * @return Returns true, if the task create extension was successful, otherwise
>> + *   false.
>> + *
>> + * @par Notes
>> + * @parblock
>> + * The task create extensions are invoked in extension forward order.
> 
> As above.
> 
>>    *
>> - * Any subsequent references to the extension's name and identifier are
>> - * invalid.
>> + * The task create extensions are invoked after a new task has been completely
>> + * initialized, but before it is started.
>>    *
>> - * This directive will not cause the calling task to be preempted.
>> + * While normal tasks are created, the executing thread is the owner of the
>> + * object allocator mutex.  The object allocator mutex allows nesting, so the
>> + * normal memory allocation routines can be used allocate memory for the
>> + * created thread.
>>    *
>> - * @retval RTEMS_SUCCESSFUL Extension set deleted successfully.
>> - * @retval RTEMS_INVALID_ID Invalid extension set identifier.
>> + * If the task create extension returns false, then the task create operation
>> + * stops immediately and the entire task create operation will fail.  In this
>> + * case, all task delete extensions are invoked, see
>> + * ::rtems_task_delete_extension.
>> + * @endparblock
>> + *
>> + * @par Constraints
>> + * @parblock
>> + * The following constraints apply to functions of this type:
>> + *
>> + * * While the system is initialized, thread dispatching is disabled.
>> + *
>> + * * While the system is in the multitasking state, thread dispatching is
>> + *   enabled.
>> + *
>> + * * While an idle thread or another internal system thread is created, the
>> + *   object allocator mutex has no owner.
>> + *
>> + * * While a task is created by rtems_task_create(), the executing thread is
>> + *   the owner of the object allocator mutex.
>> + *
>> + * * While a task is constructed by rtems_task_construct(), the executing
>> + *   thread is the owner of the object allocator mutex.
>> + *
>> + * * While a task is created by pthread_create(), the executing thread is the
>> + *   owner of the object allocator mutex.
>> + * @endparblock
>>    */
>> -rtems_status_code rtems_extension_delete(
>> -  rtems_id id
>> -);
>> +typedef User_extensions_thread_create_extension rtems_task_create_extension;
>> +
>> +/* Generated from spec:/rtems/userext/if/task-delete */
>>   
>> -/** @} */
>> +/**
>> + * @ingroup RTEMSAPIClassicUserExt
>> + *
>> + * @brief Task delete extensions are invoked when a task is deleted.
>> + *
>> + * @param executing is the TCB of the executing thread.  If the idle thread is
>> + *   created and one of the initial task create extension fails, then the
>> + *   executing thread is equal to NULL.
>> + *
>> + * @param created is the TCB of the deleted thread.  The executing and deleted
>> + *   arguments are never equal.
>> + *
>> + * @par Notes
>> + * @parblock
>> + * The task delete extensions are invoked in extension reverse order.
>> + *
>> + * The task delete extensions are invoked by task create directives before an
>> + * attempt to allocate a TCB is made.
>> + *
>> + * If a task create extension failed, then a task delete extension may be
>> + * invoked without a previous invocation of the corresponding task create
>> + * extension of the extension set.
>> + * @endparblock
>> + *
>> + * @par Constraints
>> + * @parblock
>> + * The following constraints apply to functions of this type:
>> + *
>> + * * While the system is initialized, thread dispatching is disabled.
>> + *
>> + * * While the system is in the multitasking state, thread dispatching is
>> + *   enabled.
>> + *
>> + * * While an idle thread or another internal system thread is created, the
>> + *   object allocator mutex has no owner.
>> + *
>> + * * While a task is created by rtems_task_create(), the executing thread is
>> + *   the owner of the object allocator mutex.
>> + *
>> + * * While a task is constructed by rtems_task_construct(), the executing
>> + *   thread is the owner of the object allocator mutex.
>> + *
>> + * * While a task is created by pthread_create(), the executing thread is the
>> + *   owner of the object allocator mutex.
>> + * @endparblock
>> + */
>> +typedef User_extensions_thread_delete_extension rtems_task_delete_extension;
>> +
>> +/* Generated from spec:/rtems/userext/if/task-exitted */
>> +
>> +/**
>> + * @ingroup RTEMSAPIClassicUserExt
>> + *
>> + * @brief Task exitted extensions are invoked when a task entry returns.
>> + *
>> + * @param executing is the TCB of the executing thread.
>> + *
>> + * @par Notes
>> + * The task exitted extensions are invoked in extension forward order.
>> + *
>> + * @par Constraints
>> + * @parblock
>> + * The following constraints apply to functions of this type:
>> + *
>> + * * Thread dispatching is enabled.
>> + * @endparblock
>> + */
>> +typedef User_extensions_thread_exitted_extension rtems_task_exitted_extension;
>> +
>> +/* Generated from spec:/rtems/userext/if/task-restart */
>> +
>> +/**
>> + * @ingroup RTEMSAPIClassicUserExt
>> + *
>> + * @brief Task restart extensions are invoked when a task restarts.
>> + *
>> + * @param executing is the TCB of the executing thread.
>> + *
>> + * @param restarted is the TCB of the executing thread.  Yes, the executing
>> + *   thread.
>> + *
>> + * @par Notes
>> + * @parblock
>> + * The task restart extensions are invoked in extension forward order.
>> + *
>> + * The task restart extensions are invoked in the context of the restarted
>> + * thread right before the execution context is reloaded.  The thread stack
>> + * reflects the previous execution context.
>> + *
>> + * Thread restart and delete requests issued by restart extensions lead to
>> + * recursion.
>> + * @endparblock
>> + *
>> + * @par Constraints
>> + * @parblock
>> + * The following constraints apply to functions of this type:
>> + *
>> + * * Thread dispatching is enabled.
>> + *
>> + * * Thread life is protected.
>> + *
>> + * * The executing thread is not the owner of the object allocator mutex.
>> + * @endparblock
>> + */
>> +typedef User_extensions_thread_restart_extension rtems_task_restart_extension;
>> +
>> +/* Generated from spec:/rtems/userext/if/task-start */
>> +
>> +/**
>> + * @ingroup RTEMSAPIClassicUserExt
>> + *
>> + * @brief Task start extensions are invoked when a task was made ready for the
>> + *   first time.
>> + *
>> + * @param executing is the TCB of the executing thread.
>> + *
>> + * @param started is the TCB of the started thread.
>> + *
>> + * @par Notes
>> + * @parblock
>> + * The task start extensions are invoked in extension forward order.
>> + *
>> + * In SMP configurations, the thread may already run on another processor
>> + * before the task start extensions are actually invoked.  Task switch and task
>> + * begin extensions may run before or in parallel with the thread start
>> + * extension in SMP configurations, see ::rtems_task_switch_extension and
>> + * ::rtems_task_begin_extension.
> 
> I did not know this about SMP. Which context is this handler invoked in? The
> terminate below describes this nicely.

See below for the context:

> 
>> + * @endparblock
>> + *
>> + * @par Constraints
>> + * @parblock
>> + * The following constraints apply to functions of this type:
>> + *
>> + * * Thread dispatching is disabled.
>> + * @endparblock
>> + */
>> +typedef User_extensions_thread_start_extension rtems_task_start_extension;
>> +
>> +/* Generated from spec:/rtems/userext/if/task-switch */
>> +
>> +/**
>> + * @ingroup RTEMSAPIClassicUserExt
>> + *
>> + * @brief Task switch extensions are invoked when a thread switch from an
>> + *   executing thread to a heir thread takes place.
>> + *
>> + * @param executing is the TCB of the executing thread.  In SMP configurations,
>> + *   this is the previously executing thread also known as the ancestor thread.
>> + *
>> + * @param heir is the TCB of the heir thread.  In SMP configurations, this is
>> + *   the executing thread.
>> + *
>> + * @par Notes
>> + * @parblock
>> + * The task switch extensions are invoked in extension forward order.
>> + *
>> + * The invocation conditions of the task switch extensions depend on whether
>> + * RTEMS was build with SMP support enabled or disabled.  A user must pay
> 
> Built not build. It is "was built" or "is built"?
> 
>> + * attention to the differences to correctly implement a task switch extension.
>> + *
>> + * Where the system was built with SMP support disabled, the task switch
> 
> Was or is? A few other spots below depending on what is decided.

You are the native speaker ;-)

This phrase is used in several places. I don't know what is better 
English "was built" or "is built".

-- 
embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: sebastian.huber at embedded-brains.de
phone: +49-89-18 94 741 - 16
fax:   +49-89-18 94 741 - 08

Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/


More information about the devel mailing list