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

5
Last change on this file since 39773ce was b1e3b75, checked in by Sebastian Huber <sebastian.huber@…>, on 01/26/17 at 14:10:49

c-user: Rework user extensions chapter

Update #2692.
Update #2752.

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