source: rtems-docs/c-user/user_extensions.rst @ c65aeed

5
Last change on this file since c65aeed was 3a594a9, checked in by Sebastian Huber <sebastian.huber@…>, on 01/05/18 at 10:05:55

c-user: Clarify user extensions

  • Property mode set to 100644
File size: 19.0 KB
Line 
1.. comment SPDX-License-Identifier: CC-BY-SA-4.0
2
3.. COMMENT: COPYRIGHT (c) 1988-2008.
4.. COMMENT: On-Line Applications Research Corporation (OAR).
5.. COMMENT: All rights reserved.
6
7.. index:: user extensions
8
9.. _User Extensions Manager:
10
11User Extensions Manager
12***********************
13
14Introduction
15============
16
17The user extensions manager allows the application developer to augment the
18executive by allowing them to supply extension routines which are invoked at
19critical system events.  The directives provided by the user extensions manager
20are:
21
22- rtems_extension_create_ - Create an extension set
23
24- rtems_extension_ident_ - Get ID of an extension set
25
26- rtems_extension_delete_ - Delete an extension set
27
28Background
29==========
30
31User extensions (call-back functions) are invoked by the system when the
32following events occur
33
34- thread creation,
35
36- thread start,
37
38- thread restart,
39
40- thread switch,
41
42- thread begin,
43
44- thread exitted (return from thread entry function),
45
46- thread termination,
47
48- thread deletion, and
49
50- fatal error detection (system termination).
51
52The user extensions have event-specific arguments, invocation orders and
53execution contexts.  Extension sets can be installed at run-time via
54:ref:`rtems_extension_create() <rtems_extension_create>` (dynamic extension
55sets) or at link-time via the application configuration option
56:ref:`CONFIGURE_INITIAL_EXTENSIONS <CONFIGURE_INITIAL_EXTENSIONS>` (initial
57extension sets).
58
59The execution context of user extensions varies.  Some user extensions are
60invoked with ownership of the allocator mutex.  The allocator mutex protects
61dynamic memory allocations and object creation/deletion.  Some user extensions
62are invoked with thread dispatching disabled.  The fatal error extension is
63invoked in an arbitrary context.
64
65.. index:: user extension set
66.. index:: rtems_extensions_table
67
68Extension Sets
69--------------
70
71User extensions are maintained as a set.  All user extensions are optional and
72may be `NULL`.  Together a set of these user extensions typically performs a
73specific functionality such as performance monitoring or debugger support.  The
74extension set is defined via the following structure.
75
76.. code-block:: c
77
78    typedef struct {
79      rtems_task_create_extension    thread_create;
80      rtems_task_start_extension     thread_start;
81      rtems_task_restart_extension   thread_restart;
82      rtems_task_delete_extension    thread_delete;
83      rtems_task_switch_extension    thread_switch;
84      rtems_task_begin_extension     thread_begin;
85      rtems_task_exitted_extension   thread_exitted;
86      rtems_fatal_extension          fatal;
87      rtems_task_terminate_extension thread_terminate;
88    } rtems_extensions_table;
89
90.. index:: TCB extension area
91
92TCB Extension Area
93------------------
94
95There is no system-provided storage for the initial extension sets.
96
97The task control block (TCB) contains a pointer for each dynamic extension set.
98The pointer is initialized to `NULL` during thread initialization before the
99thread create extension is invoked.  The pointer may be used by the dynamic
100extension set to maintain thread-specific data.
101
102The TCB extension is an array of pointers in the TCB. The index into the table
103can be obtained from the extension identifier returned when the extension
104object is created:
105
106.. index:: rtems extensions table index
107
108.. code-block:: c
109
110    index = rtems_object_id_get_index( extension_id );
111
112The number of pointers in the area is the same as the number of dynamic user
113extension sets configured.  This allows an application to augment the TCB with
114user-defined information.  For example, an application could implement task
115profiling by storing timing statistics in the TCB's extended memory area.  When
116a task context switch is being executed, the thread switch extension could read
117a real-time clock to calculate how long the task being swapped out has run as
118well as timestamp the starting time for the task being swapped in.
119
120If used, the extended memory area for the TCB should be allocated and the TCB
121extension pointer should be set at the time the task is created or started by
122either the thread create or thread start extension.  The application is
123responsible for managing this extended memory area for the TCBs.  The memory
124may be reinitialized by the thread restart extension and should be deallocated
125by the thread delete extension  when the task is deleted.  Since the TCB
126extension buffers would most likely be of a fixed size, the RTEMS partition
127manager could be used to manage the application's extended memory area.  The
128application could create a partition of fixed size TCB extension buffers and
129use the partition manager's allocation and deallocation directives to obtain
130and release the extension buffers.
131
132Order of Invocation
133-------------------
134
135The user extensions are invoked in either `forward` or `reverse` order.  In
136forward order, the user extensions of initial extension sets are invoked before
137the user extensions of the dynamic extension sets.  The forward order of
138initial extension sets is defined by the initial extension sets table index.
139The forward order of dynamic extension sets is defined by the order in which
140the dynamic extension sets were created.  The reverse order is defined
141accordingly.  By invoking the user extensions in this order, extensions can be
142built upon one another.  At the following system events, the user extensions
143are invoked in `forward` order
144
145- thread creation,
146
147- thread start,
148
149- thread restart,
150
151- thread switch,
152
153- thread begin,
154
155- thread exitted (return from thread entry function), and
156
157- fatal error detection.
158
159At the following system events, the user extensions are invoked in `reverse`
160order:
161
162- thread termination, and
163
164- thread deletion.
165
166At these system events, the user extensions are invoked in reverse order to insure
167that if an extension set is built upon another, the more complicated user extension
168is invoked before the user extension it is built upon.  An example is use of the
169thread delete extension by the Standard C Library.  Extension sets which are
170installed after the Standard C Library will operate correctly even if they
171utilize the C Library because the C Library's thread delete extension is
172invoked after that of the other thread delete extensions.
173
174.. index:: rtems_task_create_extension
175
176Thread Create Extension
177-----------------------
178
179The thread create extension is invoked during thread creation, for example
180via :ref:`rtems_task_create() <rtems_task_create>` or :c:func:`pthread_create`.
181The thread create extension is defined as follows.
182
183.. code-block:: c
184
185    typedef bool ( *rtems_task_create_extension )(
186      rtems_tcb *executing,
187      rtems_tcb *created
188    );
189
190The :c:data:`executing` is a pointer to the TCB of the currently executing
191thread.  The :c:data:`created` is a pointer to the TCB of the created thread.
192The created thread is completely initialized with respect to the operating
193system.
194
195The executing thread is the owner of the allocator mutex except during creation
196of the idle threads.  Since the allocator mutex allows nesting the normal
197memory allocation routines can be used.
198
199A thread create extension will frequently attempt to allocate resources.  If
200this allocation fails, then the thread create extension must return
201:c:data:`false` and the entire thread create operation will fail, otherwise it
202must return :c:data:`true`.
203
204The thread create extension is invoked in forward order with thread dispatching
205enabled (except during system initialization).
206
207.. index:: rtems_task_start_extension
208
209Thread Start Extension
210----------------------
211
212The thread start extension is invoked during a thread start, for example
213via :ref:`rtems_task_start() <rtems_task_start>` or :c:func:`pthread_create`.
214The thread start extension is defined as follows.
215
216.. code-block:: c
217
218    typedef void ( *rtems_task_start_extension )(
219      rtems_tcb *executing,
220      rtems_tcb *started
221    );
222
223The :c:data:`executing` is a pointer to the TCB of the currently executing
224thread.  The :c:data:`started` is a pointer to the TCB of the started thread.
225It is invoked after the environment of the started thread has been loaded and the
226started thread has been made ready.  So, in SMP configurations, the thread may
227already run on another processor before the thread start extension is actually
228invoked.  Thread switch and thread begin extensions may run before or in
229parallel with the thread start extension in SMP configurations.
230
231The thread start extension is invoked in forward order with thread dispatching
232disabled.
233
234.. index:: rtems_task_restart_extension
235
236Thread Restart Extension
237------------------------
238
239The thread restart extension is invoked during a thread restart, for example
240via :ref:`rtems_task_restart() <rtems_task_start>`.
241The thread restart extension is defined as follows.
242
243.. code-block:: c
244
245    typedef void ( *rtems_task_restart_extension )(
246      rtems_tcb *executing,
247      rtems_tcb *restarted
248    );
249
250Both :c:data:`executing` and :c:data:`restarted` are pointers the TCB of the
251currently executing thread.  It is invoked in the context of the executing
252thread right before the execution context is reloaded.  The thread stack
253reflects the previous execution context.
254
255The thread restart extension is invoked in forward order with thread
256dispatching enabled (except during system initialization).  The thread life is
257protected.  Thread restart and delete requests issued by thread restart
258extensions lead to recursion.  The POSIX cleanup handlers, POSIX key
259destructors and thread-local object destructors run in this context.
260
261.. index:: rtems_task_switch_extension
262
263Thread Switch Extension
264-----------------------
265
266The thread switch extension is invoked before the context switch from the
267currently executing thread to the heir thread.  The thread switch extension is
268defined as follows.
269
270.. code-block:: c
271
272    typedef void ( *rtems_task_switch_extension )(
273      rtems_tcb *executing,
274      rtems_tcb *heir
275    );
276
277The :c:data:`executing` is a pointer to the TCB of the currently executing
278thread.  The :c:data:`heir` is a pointer to the TCB of the heir thread.
279
280The thread switch extension is invoked in forward order with thread dispatching
281disabled.  In SMP configurations, interrupts are disabled and the per-processor
282SMP lock is owned.  Thread switch extensions may run in parallel on multiple
283processors.  It is recommended to use thread-local or per-processor data
284structures in SMP configurations for thread switch extensions.  A global SMP
285lock should be avoided for performance reasons.
286
287The context switches initiated through the multitasking start are not covered
288by the thread switch extension.
289
290.. index:: rtems_task_begin_extension
291
292Thread Begin Extension
293----------------------
294
295The thread begin extension is invoked during a thread begin before the thread
296entry function is called.  The thread begin extension is defined as follows.
297
298.. code-block:: c
299
300    typedef void ( *rtems_task_begin_extension )(
301      rtems_tcb *executing
302    );
303
304The :c:data:`executing` is a pointer to the TCB of the currently executing
305thread.  The thread begin extension executes in a normal thread context and may
306allocate resources for the executing thread.  In particular, it has access to
307thread-local storage of the executing thread.
308
309The thread begin extension is invoked in forward order with thread dispatching
310enabled.  The thread switch extension may be called multiple times for this
311thread before or during the thread begin extension is invoked.
312
313.. index:: rtems_task_exitted_extension
314
315Thread Exitted Extension
316------------------------
317
318The thread exitted extension is invoked once the thread entry function returns.
319The thread exitted extension is defined as follows.
320
321.. code-block:: c
322
323    typedef void ( *rtems_task_exitted_extension )(
324      rtems_tcb *executing
325    );
326
327The :c:data:`executing` is a pointer to the TCB of the currently executing
328thread.
329
330This extension is invoked in forward order with thread dispatching enabled.
331
332.. index:: rtems_task_terminate_extension
333
334Thread Termination Extension
335----------------------------
336
337The thread termination extension is invoked in case a termination request is
338recognized by the currently executing thread.  Termination requests may result
339due to calls of :ref:`rtems_task_delete() <rtems_task_delete>`,
340:c:func:`pthread_exit`, or :c:func:`pthread_cancel`.  The thread termination
341extension is defined as follows.
342
343.. code-block:: c
344
345    typedef void ( *rtems_task_terminate_extension )(
346      rtems_tcb *executing
347    );
348
349The :c:data:`executing` is a pointer to the TCB of the currently executing
350thread.
351
352It is invoked in the context of the terminated thread right before the thread
353dispatch to the heir thread.  The POSIX cleanup handlers, POSIX key destructors
354and thread-local object destructors run in this context.  Depending on the
355order, the thread termination extension has access to thread-local storage and
356thread-specific data of POSIX keys.
357
358The thread terminate extension is invoked in reverse order with thread
359dispatching enabled.  The thread life is protected.  Thread restart and delete
360requests issued by thread terminate extensions lead to recursion.
361
362.. index:: rtems_task_delete_extension
363
364Thread Delete Extension
365-----------------------
366
367The thread delete extension is invoked in case a zombie thread is killed.  A
368thread becomes a zombie thread after it terminated.  The thread delete
369extension is defined as follows.
370
371.. code-block:: c
372
373    typedef void ( *rtems_task_delete_extension )(
374      rtems_tcb *executing,
375      rtems_tcb *deleted
376    );
377
378The :c:data:`executing` is a pointer to the TCB of the currently executing
379thread.  The :c:data:`deleted` is a pointer to the TCB of the deleted thread.
380The :c:data:`executing` and :c:data:`deleted` pointers are never equal.
381
382The executing thread is the owner of the allocator mutex.  Since the allocator
383mutex allows nesting the normal memory allocation routines can be used.
384
385The thread delete extension is invoked in reverse order with thread dispatching
386enabled.
387
388Please note that a thread delete extension is not immediately invoked with a
389call to :ref:`rtems_task_delete() <rtems_task_delete>` or similar.  The thread
390must first terminate and this may take some time.  The thread delete extension
391is invoked by :ref:`rtems_task_create() <rtems_task_create>` or similar as a
392result of a lazy garbage collection of zombie threads.
393
394.. index:: rtems_fatal_extension
395
396Fatal Error Extension
397---------------------
398
399The fatal error extension is invoked during :ref:`system termination
400<Terminate>`.  The fatal error extension is defined as follows.
401
402.. code-block:: c
403
404    typedef void( *rtems_fatal_extension )(
405      rtems_fatal_source source,
406      bool               always_set_to_false,
407      rtems_fatal_code   code
408    );
409
410The :c:data:`source` parameter is the fatal source indicating the subsystem the
411fatal condition originated in.  The :c:data:`always_set_to_false` parameter is
412always set to :c:data:`false` and provided only for backward compatibility
413reasons.  The :c:data:`code` parameter is the fatal error code.  This value
414must be interpreted with respect to the source.
415
416The fatal error extension is invoked in forward order.
417
418It is strongly advised to use initial extension sets to install a fatal error
419extension.  Usually, the initial extension set of board support package
420provides a fatal error extension which resets the board.  In this case, the
421dynamic fatal error extensions are not invoked.
422
423Directives
424==========
425
426This section details the user extension manager's directives.  A subsection is
427dedicated to each of this manager's directives and describes the calling
428sequence, related constants, usage, and status codes.
429
430.. raw:: latex
431
432   \clearpage
433
434.. index:: create an extension set
435.. index:: rtems_extension_create
436
437.. _rtems_extension_create:
438
439EXTENSION_CREATE - Create a extension set
440-----------------------------------------
441
442CALLING SEQUENCE:
443    .. code-block:: c
444
445        rtems_status_code rtems_extension_create(
446          rtems_name                    name,
447          const rtems_extensions_table *table,
448          rtems_id                     *id
449        );
450
451DIRECTIVE STATUS CODES:
452    .. list-table::
453     :class: rtems-table
454
455     * - ``RTEMS_SUCCESSFUL``
456       - extension set created successfully
457     * - ``RTEMS_INVALID_NAME``
458       - invalid extension set name
459     * - ``RTEMS_TOO_MANY``
460       - too many extension sets created
461
462DESCRIPTION:
463
464    This directive creates an extension set object and initializes it using the
465    specified extension set table.  The assigned extension set identifier is
466    returned in :c:data:`id`.  This identifier is used to access the extension
467    set with other user extension manager directives.  For control and
468    maintenance of the extension set, RTEMS allocates an Extension Set Control
469    Block (ESCB) from the local ESCB free pool and initializes it.  The
470    user-specified :c:data:`name` is assigned to the ESCB and may be used to
471    identify the extension set via
472    :ref:`rtems_extension_ident() <rtems_extension_ident>`.  The extension set
473    specified by :c:data:`table` is copied to the ESCB.
474
475NOTES:
476
477    This directive will not cause the calling task to be preempted.
478
479.. raw:: latex
480
481   \clearpage
482
483.. index:: get ID of an extension set
484.. index:: obtain ID of an extension set
485.. index:: rtems_extension_ident
486
487.. _rtems_extension_ident:
488
489EXTENSION_IDENT - Get ID of a extension set
490-------------------------------------------
491
492CALLING SEQUENCE:
493    .. code-block:: c
494
495        rtems_status_code rtems_extension_ident(
496          rtems_name  name,
497          rtems_id   *id
498        );
499
500DIRECTIVE STATUS CODES:
501    .. list-table::
502     :class: rtems-table
503
504     * - ``RTEMS_SUCCESSFUL``
505       - extension set identified successfully
506     * - ``RTEMS_INVALID_NAME``
507       - extension set name not found
508
509DESCRIPTION:
510    This directive obtains the extension set identifier associated with the
511    extension set :c:data:`name` to be acquired and returns it in :c:data:`id`.
512    If the extension set name is not unique, then the extension set identifier
513    will match one of the extension sets with that name.  However, this
514    extension set identifier is not guaranteed to correspond to the desired
515    extension set.  The extension set identifier is used to access this
516    extension set in other extension set related directives.
517
518NOTES:
519    This directive will not cause the running task to be preempted.
520
521.. raw:: latex
522
523   \clearpage
524
525.. index:: delete an extension set
526.. index:: rtems_extension_delete
527
528.. _rtems_extension_delete:
529
530EXTENSION_DELETE - Delete a extension set
531-----------------------------------------
532
533CALLING SEQUENCE:
534    .. code-block:: c
535
536        rtems_status_code rtems_extension_delete(
537            rtems_id id
538        );
539
540DIRECTIVE STATUS CODES:
541    .. list-table::
542     :class: rtems-table
543
544     * - ``RTEMS_SUCCESSFUL``
545       - extension set deleted successfully
546     * - ``RTEMS_INVALID_ID``
547       - invalid extension set id
548
549DESCRIPTION:
550    This directive deletes the extension set specified by :c:data:`id`.  If the
551    extension set is running, it is automatically canceled.  The ESCB for the
552    deleted extension set is reclaimed by RTEMS.
553
554NOTES:
555    This directive will not cause the running task to be preempted.
556
557    A extension set can be deleted by a task other than the task which created
558    the extension set.
Note: See TracBrowser for help on using the repository browser.